15. Move Zeroes
easyAsked at IntuitMove 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 Sam K., 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 - 1Must operate in-place (no auxiliary array).
Examples
Example 1
nums = [0,1,0,3,12][1,3,12,0,0]Example 2
nums = [0][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.
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.