Just create a new array. Then copy over the non-zero elements in order and done.
defmoveZeroes(self,nums: List[int])-> List[int]: n =len(nums)if n ==0:return copy_array =[0for i inrange(n)] non_zero_index =0for ele in nums:if ele !=0: copy_array[non_zero_index]= ele non_zero_index +=1return copy_array
The time complexity is O(n). The space complexity is also O(n).
Brute Force Approach
Brute Force Code
Version1: Swapping zeroes to the end
Version 2: Swapping non-zero elements to the front
Slower with O(n2) time but in place
Better Approach
Store a count for zero shift every up then pad zeroes. The tricky park is how to count and shift.
Code
Alternative Approach
We can do something similar to first approach but have to swap. Swap after the last non-zero element with a single scan.
O(n) time with O(1) space
Proof sketch
Assume there is a dummy non-zero element before the list. Every element has 2 cases, zero or non-zero. For zero, we can simply ignore them. For non-zero, if it gets swapped right after the previous non-zero element, then the relative ordering is kept and there is no zeroes between the non-zero elements. Non-zero element will never get swapped with another non-zero element because if a non-zero element appears right after another non-zero element then it will just swap with itself. If a non-zero element does not appear right after another non-zero element, then that means there must be some zeroes between them and swapping with zeroes is fine in that sense that we don't have to keep a relative ordering of the zeroes.
Scan from right to left
if detect a zero call swapToRight function - swap is an in-place operation
public int[] moveZeroes(int[] array) {
if (array == null || array.length <= 1) {
return array;
}
int size = array.length;
for (int i = size - 1; i >= 0; i--) {
if (array[i] == 0) {
moveZero(array, i);
}
}
return array;
}
/*
* Swap the zero all the way to the right
* Stop when reaches the end or reaches another 0
*/
private void moveZero(int[] array, int swapIndex) {
int size = array.length;
while (swapIndex + 1 < size && array[swapIndex + 1] != 0) {
array[swapIndex] = array[swapIndex + 1];
array[swapIndex + 1] = 0;
swapIndex++;
}
}
def moveZeroes(nums: List[int]) -> None:
n = len(nums)
if n == 0:
return
for i in range(n):
if nums[i] != 0:
swap_to_front(nums, i)
def swap_to_front(nums: List[int], i: int) -> None:
while i > 0 and nums[i-1] == 0:
swap(nums, i, i-1)
i -= 1
def swap(nums: List[int], i: int, j: int) -> None:
temp = nums[i]
nums[i] = nums[j]
nums[j] = temp
Scan the array from left to right
if the element is not 0, shift it up by the number of zeroes we have so far
if it is 0, then increase the count of the 0s
public void moveZeroes(int[] nums) {
if (nums == null || nums.length <= 1) {
return;
}
int size = nums.length;
int numOfZeroes = 0;
// Step 1 Shift all elements to the zeroes before them
for (int i = 0; i < size; i++) {
if (nums[i] == 0) {
numOfZeroes++;
} else {
nums[i - numOfZeroes] = nums[i];
}
}
// Step 2 Pad zeroes in the end
for (int j = size - numOfZeroes; j < size; j++) {
nums[j] = 0;
}
}
def moveZeroes(self, nums: List[int]) -> None:
n = len(nums)
if n == 0:
return
last = 0
for i in range(n):
if nums[i] != 0:
# swap after the last non-zero element
swap(nums, i, last)
last += 1