Last Updated: February 6, 2026
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 that you must do this in-place without making a copy of the array.
Follow up: Could you minimize the total number of operations done?
At first glance, this problem seems trivial: just find the zeros and move them to the end. But there are several constraints that make it interesting:
Let's visualize what we need to achieve:
The non-zero elements [1, 3, 12] maintain their relative order. The zeros have been pushed to the end.
A key observation is that we need to "shift" all non-zero elements to the front of the array. Once all non-zeros are in their correct positions at the front, whatever remains at the back will naturally be zeros.
The most intuitive approach is to create a temporary array, copy all non-zero elements first, then fill the remaining positions with zeros. While this violates the in-place constraint, it helps us understand the core logic before optimizing.
Input:
After the first pass (collect non-zeroes into result):
The second pass fills the remaining positions with zero (they may already be zero, but that’s fine):
Finally, we copy result back into nums:
This approach works correctly but uses extra space. Let's improve it.
We can achieve an in-place solution by breaking the problem into two phases:
Think of it like compacting a file system: first, move all the "used" blocks to the front, then mark the rest as "free" (zeros).
writePos at 0 to track where the next non-zero element should gowritePos and increment writePoswritePos tells us where the zeros should startwritePos to the end with zerosInput:
After first pass:
After second pass:
We can fine-tune our previous two-pointer approach by swapping in place.
Maintain two indices:
Whenever nums[readPos] is non-zero, swap it with nums[writePos] (only if readPos != writePos) and advance writePos. This compacts non-zeros in a single pass and leaves zeros behind naturally.