Move Zeroes
Move every zero to the end while keeping the order of the non-zero values, in place. A write pointer w marks where the next non-zero belongs; the read pointer swaps each non-zero into place.
Traced input: nums = [0, 1, 0, 3, 12] → [1, 3, 12, 0, 0]. Original problem: neetcode.io/problems/move-zeroes
Complexity
BestO(n)
AverageO(n)
WorstO(n)
SpaceO(1)
One pass, in place.
Key idea
- Everything left of
wis the non-zero values in their original order. - When
rfinds a non-zero, swap it towand advancew. - Swapping (instead of overwriting) leaves the zeros behind at the end automatically.
Common mistakes
- Overwriting and then filling zeros works too, but takes two passes.
- Moving zeros by shifting elements is O(n²).
- Swapping when
w == ris harmless; don't add special cases for it.
Solution
Java
void moveZeroes(int[] nums) {
int w = 0;
for (int r = 0; r < nums.length; r++) {
if (nums[r] == 0) {
continue;
}
int tmp = nums[w]; nums[w] = nums[r]; nums[r] = tmp;
w++;
}
}Python
def moveZeroes(nums: List[int]) -> None:
w = 0
for r in range(len(nums)):
if nums[r] == 0:
continue
nums[w], nums[r] = nums[r], nums[w]
w += 1C++
void moveZeroes(vector<int>& nums) {
int w = 0;
for (int r = 0; r < (int)nums.size(); r++) {
if (nums[r] == 0) {
continue;
}
swap(nums[w], nums[r]);
w++;
}
}Edge cases
Each one has its own trace in the interactive view.
| Case | Input | Answer |
|---|---|---|
| No zeros Each element swaps with itself. | nums = [1, 2, 3] | [1, 2, 3] |
All zerosw never moves. | nums = [0, 0, 0] | [0, 0, 0] |
| Single element Nothing to move. | nums = [0] | [0] |
| Zeros already at the end Order is preserved. | nums = [4, 2, 0, 0] | [4, 2, 0, 0] |
| Negative values Only zero is special; negatives are kept in order. | nums = [0, -1, 0, -2] | [-1, -2, 0, 0] |