Description
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?
Constraints
1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
Examples
- Example 1:
Input:nums = [0, 1, 0, 3, 12]
Output:[1, 3, 12, 0, 0]
- Example: 2
Input:nums = [0]
Output:[0]
Solution 1: Brute-Force
Steps
- Iterate through the entire array starting from the last element of
nums
:- If the current element is not
0
, skip this iteration. - If not, shift the entire right substring one position to the left and add a
0
at the end.
- If the current element is not
Codes
def move_zeros(nums: List[int]) -> None:
for i in range(len(nums) - 1, -1, -1):
if nums[i] != 0:
continue
else:
for j in range(i, len(nums) - 1):
nums[j] = nums[j + 1]
nums[len(nums) - 1] = 0
PythonComplexities
- Time Complexity:
O(N2)
, whereN
is the length of thenums
array. - Space Complexity:
O(1)
Solution 2: Two Pointers
Thought
During the iteration of nums
, if we can continuously track the position where each non-zero element should be inserted, we can use a two-pointer approach to insert non-zero elements in their corresponding positions in a single pass.
Steps
- Use two pointers,
i
andj
, to iterate through the entirenums
array. Thei
pointer represents the position where non-zero elements will be inserted, and thej
pointer is used to find the next non-zero element. Both pointers start at the position0
. - Continue moving the
j
pointer until the end of thenums
array, and during the traversal:- If the current element at the
j
pointer is0
, continue moving thej
pointer. - If the current element at the
j
pointer is non-zero, move the current element to the position of thei
pointer and simultaneously move both thei
andj
pointers.
- If the current element at the
- When the
j
pointer reaches the end ofnums
, since we have moved all non-zero elements to the left side ofnums
, you can now replace all elements from the current position of thei
pointer to the end ofnums
with0
‘s.
Codes
def move_zeros(nums: List[int]) -> None:
i, j = 0, 0
while i <= j:
if i == len(nums):
break
elif j == len(nums):
nums[i] = 0
i += 1
elif nums[j] != 0:
nums[i] = nums[j]
i += 1
j += 1
else:
j += 1
PythonComplexities
- Time Complexity:
O(N)
, whereN
is the length of thenums
array. - Space Complexity:
O(1)
Solution 3: Iteration and Counting
Thought
From the example, we can observe that after the entire movement of nums
, each non-zero element moves a certain distance to the left, which is exactly the total count of zeros encountered up to the current element. Therefore, we can use this characteristic to continuously calculate the total count of zeros encountered during traversal and move each non-zero element to its corresponding position.
Steps
- Initialize a variable
zero_count
to keep track of the total count of zeros encountered so far in the traversal. - First iteration:
- If you encounter a
0
, incrementzero_count
by 1. - If you encounter a non-zero element, move the current element zero_count positions to the left.
- If you encounter a
- Second iteration:
- Replace all elements from
len(nums) - zero_count
to the end of thenums
array with0
‘s.
- Replace all elements from
Codes
def move_zeroes(nums: List[int]) -> None:
zero_count = 0
for i, num in enumerate(nums):
if num == 0:
zero_count += 1
else:
nums[i - zero_count] = num
for i in range(len(nums) - zero_count, len(nums)):
nums[i] = 0
PythonComplexities
- Time Complexity:
O(N)
, whereN
is the length of thenums
array. - Space Complexity:
O(1)
References
- LeetCode link: Move Zeroes – LeetCode