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
0at 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] = 0PythonComplexities
- Time Complexity:
O(N2), whereNis the length of thenumsarray. - 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,
iandj, to iterate through the entirenumsarray. Theipointer represents the position where non-zero elements will be inserted, and thejpointer is used to find the next non-zero element. Both pointers start at the position0. - Continue moving the
jpointer until the end of thenumsarray, and during the traversal:- If the current element at the
jpointer is0, continue moving thejpointer. - If the current element at the
jpointer is non-zero, move the current element to the position of theipointer and simultaneously move both theiandjpointers.
- If the current element at the
- When the
jpointer 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 theipointer to the end ofnumswith0‘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 += 1PythonComplexities
- Time Complexity:
O(N), whereNis the length of thenumsarray. - 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_countto keep track of the total count of zeros encountered so far in the traversal. - First iteration:
- If you encounter a
0, incrementzero_countby 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_countto the end of thenumsarray 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] = 0PythonComplexities
- Time Complexity:
O(N), whereNis the length of thenumsarray. - Space Complexity:
O(1)
References
- LeetCode link: Move Zeroes – LeetCode