Skip to main content

15. Move Zeroes

easyAsked at Intuit

Move all zeros in an array to the end while keeping the order of non-zero elements, in-place. Intuit asks this to test the two-pointer pattern and to probe whether you mutate input safely (a real issue when arrays represent ledger rows).

By Alex Chen, Founder, InterviewChamp.AI · Last verified

Source citations

Public interview reports confirming this problem appears in Intuit loops.

  • Glassdoor (2026-Q1)Intuit Mint phone screen — two-pointer warm-up after Two Sum.
  • LeetCode Discuss (2025-11)QuickBooks SWE intern screen cited this as the in-place mutation test.

Problem

Given an integer array nums, move all 0's to the end of it while maintaining the relative order of the non-zero elements. Note that you must do this in-place without making a copy of the array.

Constraints

  • 1 <= nums.length <= 10^4
  • -2^31 <= nums[i] <= 2^31 - 1
  • Must operate in-place (no auxiliary array).

Examples

Example 1

Input
nums = [0,1,0,3,12]
Output
[1,3,12,0,0]

Example 2

Input
nums = [0]
Output
[0]

Approaches

1. Copy-then-fill

Build a new array of non-zeros, then pad with zeros, then copy back. Violates 'in-place' but is the obvious naive approach.

Time
O(n)
Space
O(n)
function moveZeroes(nums) {
  const nonZero = nums.filter(n => n !== 0);
  const zeros = nums.length - nonZero.length;
  for (let i = 0; i < nums.length; i++) {
    nums[i] = i < nonZero.length ? nonZero[i] : 0;
  }
}

Tradeoff: Linear time but uses O(n) extra space. Fails the in-place constraint.

2. Two-pointer swap (optimal)

Use a write pointer that lags behind the read pointer. Write non-zeros at the write index and advance; the tail naturally fills with zeros.

Time
O(n)
Space
O(1)
function moveZeroes(nums) {
  let write = 0;
  for (let read = 0; read < nums.length; read++) {
    if (nums[read] !== 0) {
      [nums[write], nums[read]] = [nums[read], nums[write]];
      write++;
    }
  }
}

Tradeoff: Linear time, constant space, in-place. The swap variant minimizes writes versus the two-step (write then fill zeros) approach.

Intuit-specific tips

Intuit interviewers care about minimizing writes when the array represents a ledger — every write is an audit-trail event. They probe whether you'd use the swap version or the write-then-fill version; the swap minimizes total writes when most values are non-zero. Bonus signal: discuss that this pattern (compact non-matching elements then pad) shows up in remove-duplicates and remove-element problems too.

Common mistakes

  • Building a new array and reassigning the reference — fails the in-place contract.
  • Forgetting to advance the write pointer only on non-zeros.
  • Swapping when read === write (wasted work — guard if you want to minimize writes).

Follow-up questions

An interviewer at Intuit may pivot to one of these next:

  • Remove Element — drop a specific value in-place (LC 27).
  • Move all negative numbers to the front, keeping relative order.
  • Stable partition with multiple categories (not just zero / non-zero).

Solve it now

Free. No sign-up. Python and JavaScript run instantly in your browser.

Output

Press Run or Cmd+Enter to execute

FAQ

Why two pointers instead of one with a counter?

The write pointer tracks where the next non-zero belongs; the read pointer scans the whole array. Separating them keeps the invariant clean: everything before write is non-zero in original order.

How does in-place matter for ledger arrays?

If the array is a SQL result holding ledger rows, mutating in-place avoids re-allocation and preserves any object references downstream consumers hold. It also reduces GC pressure under load.

Practice these live with InterviewChamp.AI

Drill Move Zeroes and other Intuit interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.

Practice these live with InterviewChamp.AI →