đź”” Prelude: When addressing the “Move Zeroes” problem, it is simple to misinterpret Python’s parameter behavior. Remember: A local variable and a parameter sharing the same name does not mean they refer to the same object.
🖋️ Move Zeroes
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.
Example 1:
Input: nums = [0,1,0,3,12]
Output: [1,3,12,0,0]
Here’s an example of solving the “Move Zeroes” problem (a wrong one):
def moveZeroes(self, nums: List[int]) -> None:
counter = 0
while 0 in nums:
nums.remove(0)
counter += 1
nums = nums + [0] * counter
In this code, the final assignment to nums actually doesn’t affect the parameter nums because they are different variables.
Within the function, Python creates a new namespace, known as the local scope. All variables defined or assigned inside the function are, by default, considered local variables.
When you execute nums = nums + [0] * counter inside the function, Python’s interpreter assigns the new list object (from the right-hand expression) to the local variable nums. This means:
- The original
nums(the parameter) still refers to the passed-in list object. - The local variable
numsnow refers to a new list object. - The assignment
nums = ...changes the binding of the localnumsto point to the new object, leaving the original passed-in list unaffected.
A possible solution is to change the first nums to nums[:], which means you are modifying the original object.
Two-pointer Solution:
A more efficient approach to solving the “Move Zeroes” problem is using a two-pointer method:
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
left = 0
for right in range(len(nums)):
if nums[right] != 0:
nums[left], nums[right] = nums[right], nums[left]
left += 1
In this solution, left is initialized to zero, and the first element being zero does not affect the algorithm’s ability to move all zeros to the right. This two-pointer method efficiently processes the list in-place, making it a more optimal solution than the previous approach.