09. Move Zeroes to the End of Array

Difficulty:EasyPattern:Two Pointers / In-Place ShiftTime:O(n)Space:O(1)

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

How It Works & Algorithmic Design

This uses a Two-Pointer Write Boundary approach:

  1. Pointer Definition: Maintain a insertPos pointer initialized to index 0.
  2. Pass 1 (Shift Non-Zeroes): Iterate through the array with pointer $i$. Whenever nums[i] !== 0, place nums[insertPos] = nums[i] and increment insertPos++.
  3. Pass 2 (Fill Zeroes): Once all non-zero elements are moved to the front, loop from insertPos to the end of the array and set nums[i] = 0.

Why This Approach Works Best

This solves the problem in-place without creating a duplicate array ($O(1)$ space). It executes in linear $O(n)$ time complexity.

Example Walkthrough
Input: [0, 1, 0, 3, 12]
Array with scattered zeroes.
After Non-Zero Shift: [1, 3, 12, 3, 12] (insertPos = 3)
Non-zero values shifted to indices 0, 1, 2.
After Zero Fill: [1, 3, 12, 0, 0]
Indices 3 to 4 filled with zeroes.
Output: [1, 3, 12, 0, 0]
Zeroes pushed to end in-place.

Answer: Move zeroes in-place

function moveZeroes(nums) {
  let insertPos = 0;
  for (let i = 0; i < nums.length; i++) {
    if (nums[i] !== 0) {
      nums[insertPos++] = nums[i];
    }
  }
  while (insertPos < nums.length) {
    nums[insertPos++] = 0;
  }
  return nums;
}
💡 Shift non-zero items to the front, then backfill remaining indices with zeroes.
Key Takeaways
  • Maintains relative order of non-zero elements by sequentially writing to insertPos.
  • Modifies original array reference directly ($O(1)$ space).
  • Linear time complexity $O(n)$ with two sequential simple loops.