Skip to main content

283. Move Zeroes

easyAsked at Gusto

Move all zeroes to the end of an array while preserving the relative order of non-zero elements, in-place. Gusto asks this to test the two-pointer write-cursor pattern and to see if you minimise unnecessary swaps.

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

Source citations

Public interview reports confirming this problem appears in Gusto loops.

  • Glassdoor (2025-12)Reported as a Gusto phone-screen warm-up emphasising in-place array manipulation and minimising operations.
  • Blind (2025-10)Gusto threads mention Move Zeroes as a clean entry-level problem that assesses understanding of write-pointer technique.

Problem

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

Constraints

  • 1 <= nums.length <= 10^4
  • −2^31 <= nums[i] <= 2^31 − 1

Examples

Example 1

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

Explanation: Non-zero elements 1, 3, 12 are compacted to the front; zeroes fill the tail.

Example 2

Input
nums = [0]
Output
[0]

Explanation: Single zero — nothing moves.

Approaches

1. Write-cursor (two-pointer)

Maintain a write cursor. On each non-zero element, write it at the cursor position and advance the cursor. Then fill the tail with zeroes.

Time
O(n)
Space
O(1)
function moveZeroes(nums) {
  let writeIdx = 0;
  // compact non-zero elements to the front
  for (let readIdx = 0; readIdx < nums.length; readIdx++) {
    if (nums[readIdx] !== 0) {
      nums[writeIdx++] = nums[readIdx];
    }
  }
  // fill remaining positions with zeroes
  while (writeIdx < nums.length) {
    nums[writeIdx++] = 0;
  }
}

Tradeoff: O(n) time, O(1) space. Two passes but minimises writes — each element is written at most once. Cleaner than swapping.

2. Swap non-zeroes forward

Swap each non-zero element with the element at the write cursor position. Zeroes naturally migrate to the end.

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

Tradeoff: Single pass and still O(1) space, but performs redundant swaps when the current element is already at the write cursor (e.g., no zeroes encountered yet). The write-cursor version avoids this.

Gusto-specific tips

Gusto interviewers appreciate the observation that the swap approach does unnecessary work when writeIdx === i (you'd be swapping an element with itself). Mention this and prefer the two-pass write-cursor version as the more cache-friendly approach. Also note that 'in-place without a copy' rules out the filter-and-concat approach.

Common mistakes

  • Creating a new array and returning it — the problem requires in-place modification of the input array.
  • Not preserving the relative order of non-zero elements — sorting the array (zeroes to one end) breaks the order guarantee.
  • Decrementing the loop counter after swapping to re-process an element — not needed; the write cursor handles positioning.
  • Using filter() which creates a new array — violates the in-place constraint.

Follow-up questions

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

  • What if you need to move all instances of a specific value (not just zeroes) to the end?
  • How would you remove elements equal to a value in-place and return the new length? (LC 27 — Remove Element.)
  • What is the minimum number of writes required?

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 is the write-cursor approach preferred over sorting?

Sorting doesn't preserve the relative order of non-zero elements — e.g., [3,1,0,2] would become [1,2,3,0] instead of [3,1,2,0].

Does this work if there are no zeroes?

Yes. writeIdx advances with every element, so both loops finish immediately in the second phase (writeIdx equals nums.length). No writes are made.

How many writes does the write-cursor version make?

Exactly (non-zero count) + (zero count) = n writes in the worst case (many leading zeroes). The swap version may make fewer or more depending on the distribution.

Practice these live with InterviewChamp.AI

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

Practice these live with InterviewChamp.AI →