You are 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.
Example 1:
Input: nums = [0,0,1,2,0,5]
Output: [1,2,5,0,0,0]Example 2:
Input: nums = [0,1,0]
Output: [1,0,0]Constraints:
1 <= nums.length <= 10,000-(2^31) <= nums[i] <= ((2^31)-1)Follow up: Could you minimize the total number of operations done?
Before attempting this problem, you should be comfortable with:
The simplest approach is to separate non-zero elements from zeros using extra storage. We collect all non-zero elements first, then write them back to the original array, filling the remaining positions with zeros. This guarantees the relative order of non-zero elements is preserved.
tmp and add all non-zero elements from nums.tmp.length, copy the value from tmp.0.We can avoid extra space by overwriting the array in place. Use a left pointer to track where the next non-zero element should go. As we scan with a right pointer, each non-zero element gets copied to the left pointer's position. After the first pass, all non-zero elements are at the front in order. A second pass fills the remaining positions with zeros.
l = 0 to track the position for the next non-zero element.r. For each non-zero element, copy it to nums[l] and increment l.l to the end with 0.Instead of copying values and then filling zeros separately, we can swap elements in a single pass. The left pointer marks the boundary between processed non-zero elements and unprocessed elements. When we encounter a non-zero element with the right pointer, we swap it with the element at the left pointer. This naturally pushes 0 to the right while keeping non-zero elements in their relative order.
l = 0 to track the swap position.r. For each non-zero element:nums[l] and nums[r].l.When both pointers l and r point to the same non-zero element, swapping is unnecessary and wastes operations. While this does not affect correctness, adding a check like if (l != r) before swapping improves efficiency and avoids redundant writes, which can matter for performance-sensitive applications.
The problem requires maintaining the relative order of non-zero elements. Some approaches incorrectly swap non-zero elements with each other or move them out of sequence. The two-pointer technique works because the left pointer only advances when a non-zero element is placed, ensuring all non-zero elements shift left in their original order while zeros naturally accumulate at the end.