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: You must do this in-place without making a copy of the array.

Example 1:

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

Example 2:

Input: nums = [0]
Output: [0]

Constraints:

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

Follow up: Could you minimize the total number of operations done?


Visualizing Two-Pointer Technique

Watch how the slow (k) and fast (i) pointers work together to move non-zero elements forward:

0
1
0
3
12
k=0
i=0
Starting: Find non-zero elements and move them forward

Approach & Explanation

This is a classic two-pointer problem that demonstrates in-place array manipulation.

Strategy

We use a slow-fast pointer approach:

  • Fast pointer (i) scans through the array
  • Slow pointer (k) tracks the position where the next non-zero should be placed

Algorithm

  1. Initialize k = 0 (position for next non-zero element)
  2. Iterate through array with pointer i:
    • If nums[i] == 0, skip it (continue)
    • If nums[i] != 0, place it at nums[k] and increment k
  3. After the loop, fill remaining positions from k to end with zeros

Example Walkthrough

For [0, 1, 0, 3, 12]:

Initial: k=0, nums = [0, 1, 0, 3, 12]

i=0: nums[0]=0, skip
i=1: nums[1]=1, nums[k]=nums[0]=1, k=1 → [1, 1, 0, 3, 12]
i=2: nums[2]=0, skip
i=3: nums[3]=3, nums[k]=nums[1]=3, k=2 → [1, 3, 0, 3, 12]
i=4: nums[4]=12, nums[k]=nums[2]=12, k=3 → [1, 3, 12, 3, 12]

Fill zeros: k=3 to end → [1, 3, 12, 0, 0]

Complexity Analysis

  • Time: O(n) - single pass through array
  • Space: O(1) - in-place modification

Optimization Note

This solution minimizes operations by:

  • Only writing non-zero elements once
  • Avoiding unnecessary swaps when i == k

Solution

Java

class Solution {
    public void moveZeroes(int[] nums) {
        int k = 0;
        
        for (int i = 0 ; i < nums.length ; i++) {
            if(nums[i] == 0) continue;

            nums[k] = nums[i];
            k++;
        }

        while(k < nums.length) {
            nums[k++] = 0;
        }
    }
}

Go

func moveZeroes(nums []int) {
    k := 0

    for i := range nums {
        if nums[i] == 0 {
            continue
        }
        if i != k {
            nums[k] = nums[i]
        }
        k++
    }

    for k < len(nums) {
        nums[k] = 0
        k++
    }
}

Key Insight

This problem demonstrates the two-pointer pattern for in-place array modifications. The slow-fast pointer technique is a fundamental pattern used in many array manipulation problems like removing duplicates, partitioning, and rearranging elements.

The key optimization is recognizing that we don’t need to swap - we can simply overwrite positions with non-zero values and fill zeros at the end.