Skip to content

283. Move Zeroes

On LeetCode ->

Problem

Move all 0 values in nums to the end, in-place, while keeping the order of non-zero values unchanged.

Example:

nums = [0,1,0,3,12]  ->  [1,3,12,0,0]

Key trick

Use a write pointer:

  • scan left to right
  • write each non-zero at the next free position
  • fill the remaining suffix with zeroes

This is stable and in-place.

Trap

Common mistakes:

  • not preserving the order of non-zero elements
  • using extra array space
  • swapping every zero with later values, which may do more writes than needed
  • forgetting the function must mutate nums and return None

Why is it interesting?

It tests a very common pattern:

  • two pointers
  • in-place array compaction
  • stability under mutation

It also has a small optimization angle: minimize writes.

Python solution

class Solution:
    def moveZeroes(self, nums: list[int]) -> None:
        n = len(nums)
        # next position where a non-zero should go
        w = 0

        # compact all non-zero values to the front
        for x in nums:
            if x != 0:
                nums[w] = x
                w += 1

        # fill the rest with zeroes
        for i in range(w, n):
            nums[i] = 0

    def moveZeroes_2(self, nums: list[int]) -> None:
        n = len(nums)
        w = 0
        for r in range(n):
            if nums[r] != 0:
                nums[w], nums[r] = nums[r], nums[w]
                w += 1

Comment on my solution

Your solution is correct and efficient.

Good points:

  • in-place
  • stable
  • linear time
  • avoids unnecessary zero writes until needed

Small comment:

  • count_zeroes works, but write is the more standard interview pointer and is easier to explain
  • if count_zeroes: is a nice small optimization

Equivalent idea in more common form:

  • i - count_zeroes is exactly the write index
import pytest

class Solution:
    def moveZeroes(self, nums: list[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        count_zeroes = 0
        for i in range(len(nums)):
            if nums[i] == 0:
                count_zeroes += 1
            else:
                # shift left non zero numbers
                nums[i - count_zeroes] = nums[i]
                if count_zeroes:
                    nums[i] = 0


@pytest.mark.parametrize(
    ("nums", "expected"),
    [

        ([0,1,0,3,12], [1,3,12,0,0]),
        ([0], [0]),
        ([1,3,12], [1,3,12]),
        ([0,1,0,3,12,0], [1,3,12,0,0,0]),
        ([0,0,1], [1,0,0]),
        ([0,0,1,1], [1,1,0,0]),
        ([0,0,0,0,1,1], [1,1,0,0,0,0]),
        ([0,0,0,0,0,0,1,1,1], [1,1,1,0,0,0,0,0,0])
    ]
)
def test_moveZeroes(nums, expected):
    ns = nums[:]
    Solution().moveZeroes(ns)
    assert ns == expected