Move Zeroes — The Write-Pointer Two-Pointer Pattern

Sanjeev SharmaSanjeev Sharma
4 min read

Advertisement

Problem Statement

Given an integer array nums, move all zeroes to the end of the array while preserving the relative order of the nonzero elements. You must do it in place without making a copy.

Constraints:

  • 1 <= nums.length <= 10^4
  • -2^31 <= nums[i] <= 2^31 - 1
  • Must be done in place, O(1) extra space
Input:  nums = [0, 1, 0, 3, 12]
Output: [1, 3, 12, 0, 0]
Input:  nums = [0]
Output: [0]

Why This Problem Matters

Move Zeroes is the cleanest write-pointer array interview question on LeetCode. Meta, Amazon, and Microsoft all test it because in-place mutation with O(1) memory is exactly the kind of pointer arithmetic that real systems work require.

Many candidates fall back on a copy or a swap-while-not-zero loop that breaks order. The optimal write-pointer pattern surfaces in Remove Element, Remove Duplicates, and Partition Array problems. This string FAANG warmup also exposes whether candidates understand stable partitioning.

The Core Insight

Use two pointers. The write pointer marks the next slot to receive a nonzero element. Scan with a read pointer. When we see a nonzero, write it to the write slot and advance the write pointer. After the scan, fill the rest with zeroes.

A cleaner variant swaps nums[read] with nums[write] every time read finds a nonzero. The swap maintains relative order because write trails read and only steps over zeroes.

Visual Dry Run

readwritenums
000, 1, 0, 3, 12
10swap, 1, 0, 0, 3, 12
21skip zero
31swap, 1, 3, 0, 0, 12
42swap, 1, 3, 12, 0, 0

Solution (Optimal)

class Solution:
    def moveZeroes(self, nums):
        write = 0
        for read in range(len(nums)):
            if nums[read] != 0:
                nums[write], nums[read] = nums[read], nums[write]
                write += 1
var moveZeroes = function(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++;
        }
    }
};

Time: O(n) — one pass. Space: O(1) — in-place swap.

Common Mistakes

  • Copying nonzeros into a new array, violating in-place.
  • Forgetting to fill the tail with zeros in the write-then-fill variant.
  • Swapping every iteration including zero positions, which destroys order.
  • Returning the array — the function modifies in place and returns void.

Interview Tips

  • State the brute force two-pass approach first, then the one-pass swap.
  • Walk through the swap on a small example to prove order is preserved.
  • Verbalize the invariant that all elements before write are nonzero.
  • Confirm whether the function mutates in place or returns a new array.

Follow-up Questions

  • Move zeroes to the front? Hint: scan from the right.
  • Move all instances of value k to the end? Hint: parameterize the predicate.
  • Minimize the number of writes? Hint: swap only when read does not equal write.
  • What if order need not be preserved? Hint: two pointers from both ends.
  • Generalize to move all evens to the back? Hint: use a predicate function.

Key Takeaways

  • LeetCode 283 is solved with a write pointer in O(n) and O(1) space.
  • Swap when nonzero, advance write; zeros are skipped naturally.
  • The pattern is stable partitioning — order of nonzero values is preserved.
  • Generalizes to Remove Element and Partition by Parity.
  • Always confirm in-place semantics with the interviewer.
  • Avoid creating a copy, that fails the constraint.
  • Common Meta and Amazon two-pointer warmup question.

Advertisement

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro

Related reading