LeetCode 283: Move Zeroes - All Solutions Explained
Problem Statement
The Move Zeroes problem (LeetCode 283) is an easy-level array manipulation challenge where you need to move all zeros in an array to the end while maintaining the relative order of non-zero elements.
Constraints
- 1 ≤ nums.length ≤ 10⁴
- -2³¹ ≤ nums[i] ≤ 2³¹ - 1
- Must do this in-place without making a copy of the array
Example
Input: nums = [0,1,0,3,12]
Output: [1,3,12,0,0]
Explanation of the Best Solution
This approach uses two pointers to separate zero and non-zero elements:
- Initialize Pointer:
non_zero_index = 0
- First Pass:
- Iterate through array with
i
- When
nums[i] != 0
, copy tonums[non_zero_index]
and increment - Second Pass:
- Fill remaining positions from
non_zero_index
to end with zeros
Step-by-Step Example
For nums = [0,1,0,3,12]: 1. i=0: 0 → skip 2. i=1: 1 → copy to pos 0 → [1,1,0,3,12], non_zero_index=1 3. i=2: 0 → skip 4. i=3: 3 → copy to pos 1 → [1,3,0,3,12], non_zero_index=2 5. i=4: 12 → copy to pos 2 → [1,3,12,3,12], non_zero_index=3 6. Fill zeros from index 3 → [1,3,12,0,0]
Python Code (Two Pointers Solution)
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
non_zero_index = 0
# Move all non-zero elements to front
for i in range(len(nums)):
if nums[i] != 0:
nums[non_zero_index] = nums[i]
non_zero_index += 1
# Fill remaining with zeros
for i in range(non_zero_index, len(nums)):
nums[i] = 0
# Test case
nums = [0,1,0,3,12]
Solution().moveZeroes(nums)
print(nums) # Output: [1,3,12,0,0]
Complexity
- Time Complexity: O(n) - Two passes through array
- Space Complexity: O(1) - In-place modification
- Optimizations: Minimal operations, no extra space
Why It's the Best
- Optimal O(n) time complexity
- Minimal space usage (in-place)
- Clear and easy to understand
- Preserves element order perfectly
Solution 2: Snowball Approach (Alternative)
Explanation
This approach treats zeros as a snowball that grows as we push non-zeros forward:
- Track Snowball Size:
- Count consecutive zeros
- Swap Non-Zeros:
- When encountering non-zero, swap with first zero in snowball
- Result:
- Zeros get pushed to end through swaps
Step-by-Step Example
For nums = [0,1,0,3,12]: 1. i=0: snowball=1 2. i=1: swap nums[0] and nums[1] → [1,0,0,3,12], snowball=1 3. i=2: snowball=2 4. i=3: swap nums[1] and nums[3] → [1,3,0,0,12], snowball=2 5. i=4: swap nums[2] and nums[4] → [1,3,12,0,0]
Python Code (Snowball Solution)
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
snowball = 0
for i in range(len(nums)):
if nums[i] == 0:
snowball += 1
elif snowball > 0:
nums[i - snowball], nums[i] = nums[i], 0 # Swap with first zero
# Test case
nums = [0,1,0,3,12]
Solution().moveZeroes(nums)
print(nums) # Output: [1,3,12,0,0]
Complexity
- Time Complexity: O(n) - Single pass
- Space Complexity: O(1) - In-place swaps
- Best for: When minimal writes are important
Pros and Cons
- Pros: Single pass, elegant swapping
- Cons: More swaps than two-pointer approach
- Variation: Can track first zero position instead of snowball size
Solution 3: Pythonic Approach (Not In-Place)
Explanation
This non-in-place solution demonstrates Python's capabilities but violates constraints:
- Filter and Count:
- Extract non-zeros
- Count zeros
- Combine:
- Extend with zeros
- Note: Not valid for LeetCode but good for understanding
Python Code (Non-In-Place)
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
non_zeros = [x for x in nums if x != 0]
zeros = [0] * (len(nums) - len(non_zeros))
nums[:] = non_zeros + zeros # Only works if we can assign new list
# Test case
nums = [0,1,0,3,12]
Solution().moveZeroes(nums)
print(nums) # Output: [1,3,12,0,0]
Complexity
- Time Complexity: O(n) - But creates new lists
- Space Complexity: O(n) - Extra space for new lists
- When to Use: Not for LeetCode, but for quick Python solutions
Edge Cases to Consider
- All zeros → array remains unchanged
- No zeros → array remains unchanged
- Single element array → no change needed
- All non-zeros followed by zeros → already correct
- Large input (10,000 elements) → verify performance
Final Thoughts
- Two Pointers: Best for most cases (optimal and clear)
- Snowball: Elegant single-pass alternative
- Pythonic: Demonstrates language features but invalid
- Key Insight: Tracking write position is crucial
For further practice, try similar problems like Remove Element (LeetCode 27) or Remove Duplicates from Sorted Array (LeetCode 26).