move zeros
Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements.
For example, given nums = [0, 1, 0, 3, 12], after calling your function, `nums` should be [1, 3, 12, 0, 0].
Note:
1. You must do this **in-place** without making a copy of the array.
2. Minimize the total number of operations.
Approach
Since this has to be done in in-place our only choice is to rotate the values. We can use 2 pointers i and j where i < j. Pretty much we are trying to find the first 0, then reverse it with the next instance of a non 0. We just repeat this, finding the subsequent 0 and reversing with the next non 0 until one of our pointers is greater then nums.length. At that point all the 0's would be at the end of the array.
Lets show an example for nums = [0,1,0,3,12].
i = 0, j = 1 [0, 1, 0, 3, 12] //nums[i] is 0 and nums[j] != 0 so we reverse them and increment i i = 1, j = 1 [1, 0, 0, 3, 12] //now we increment j until nums[j] != 0 i = i, j = 3 [1, 0, 0, 3, 12] //now we reverse and increment i i = 2, j = 3 [1, 3, 0, 0, 12] //increment j until nums[j] != 0 i = 2, j = 4 [1, 3, 0, 0, 12] //reverse and increment i i = 3, j = 4 [1, 3, 12, 0, 0] //increment j until nums[j] != 0 //j = 5 > nums.length so we break
Now we just have to translate this to code. One thing to notice is that when nums[i] != 0 we increment both i and j so i <= j is always true.
Solution
var moveZeroes = function(nums) {
var i = 0, j = 1;
while(j < nums.length) {
if(nums[i] === 0) {
if(nums[j] !== 0) {
nums[i] = nums[j];
nums[j] = 0;
i++;
}else{
j++;
}
}else{
i++;
j++;
}
}
};