← DSA Atlas
Dedicated problem page · #283

Move Zeroes

EasyTwo PointersSlow-fast swap that streams non-zeros forwardTwo pointers (read/write)
Solve on LeetCode ↗
283
EasyTwo PointersTwo pointers (read/write)Slow-fast swap that streams non-zeros forward

Move Zeroes

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

Open official problem prompt ↗
In plain English

Push every zero to the back of the array in place while the non-zero values keep their original ordering.

Picture it like this

Sweeping a floor: you push all the useful items to one side in the order you meet them, and the empty gaps (zeros) end up collected at the far end.

Example
Input
nums = [0, 1, 0, 3, 12]
Output
[1, 3, 12, 0, 0]
Why
The non-zeros 1, 3, 12 keep their order at the front and both zeros are pushed to the tail.
Constraints
1 <= nums.length <= 10^4-2^31 <= nums[i] <= 2^31 - 1Follow-up: minimize the total number of operations
Pattern lesson

See the pattern, then code

Slow-fast swap that streams non-zeros forward
Recognition clue

Reordering an array in-place while preserving the order of a subset (the non-zeros) is a read/write two-pointer compaction.

Two Pointers

Sorted input, opposite-end scanning, pair search, or in-place compaction.. A left pointer marks where the next non-zero belongs; as a right pointer scans, every non-zero it finds is swapped into the left slot, and the zeros are naturally left behind at the back.

New words, made simpleKnow these before the algorithm
Read/write pointers
One pointer (right) reads every element; another (left) marks where the next kept element is written.
Stable ordering
Elements that are kept preserve their original relative order.
Boundary of non-zeros
The index left, before which every element is a placed non-zero.
Approaches from first idea to best ideaCompare the trade-offs
ApproachHow it thinksCost
Extra array

Simple but allocates a second array, which the in-place requirement forbids.

Copy non-zeros into a new list, then pad with zeros, then write back.

Time O(n)Space O(n)
Overwrite then zero-fill

Correct and in-place, but writes to every trailing slot even when already zero.

Write all non-zeros to the front with one pointer, then fill the remaining slots with zeros.

Time O(n)Space O(1)
The rule we keep true

Invariant

Elements in nums[0:left] are all the non-zeros seen so far in original order, and nums[left:right] are all zeros.

Why this is correct

Reasoning

Each non-zero is swapped into position left exactly once and in the order it appears, so relative order is preserved. Because left only advances on non-zeros, all slots between left and right hold zeros; once right reaches the end, every non-zero sits compacted in front and the zeros fill the rest.

The algorithm in three movesSay these aloud before coding
1Keep left = 0 as the write position for the next non-zero

left=0 right=1 non-zero -> swap [1,0,0,3,12], left=1

2Scan right across the array

right=3 non-zero -> swap [1,3,0,0,12], left=2

3When nums[right] is non-zero, swap it with nums[left]

right=4 non-zero -> swap [1,3,12,0,0], left=3

4Advance left after each swap

5Zeros drift to the tail automatically

Visual trace

Follow the data, one decision at a time

Input snapshotHighlighted cells are involved in this example
00
11
02
33
124
1 · Readnums[0]=0
2 · AskNon-zero?
3 · Update stateleft=0
4 · ResultZero, skip; left stays 0
Key takeaway

left holds the next slot for a non-zero; right scans and swaps 1 forward first.

Code walkthrough

Read the solution in small chunks

Python 3

Do not memorize the whole program. Connect each group of lines to one job in the algorithm.

  1. 1
    Lines 3Initialize the write boundary

    left is where the next non-zero should land; it starts at the front.

  2. 2
    Lines 4Scan the whole array

    right visits every index, reading each value once.

  3. 3
    Lines 5Detect a non-zero

    Only non-zero values need to be moved forward; zeros are ignored.

  4. 4
    Lines 6-7Swap and advance

    Swap the non-zero into the boundary slot, then push the boundary forward one step.

Make it stick

Edge cases, mistakes, and one self-check

E

Edge cases to test

  • Array with no zeros (every swap is a no-op with itself)
  • Array of all zeros (left never moves)
  • Single-element array
  • Zeros already at the end
!

Common beginner mistakes

  • Copying non-zeros forward without zeroing the tail, leaving stale values behind
  • Sorting or otherwise disturbing the relative order of non-zeros
  • Returning a new list instead of mutating nums in place
  • Advancing left on zeros, which would overwrite non-zero data
Check your understanding

Why does swapping (rather than plain overwriting) preserve the relative order of non-zeros?