Move Zeroes
Problem statement
You are given a list of integers nums. Move every 0 to the end of the list, keeping the non-zero values in their original relative order. Change the list in place; do not return a new one.
Examples
Example 1
Input: nums = [0, 4, 0, 7, 2]
Output: [4, 7, 2, 0, 0]
Explanation: 4, 7, 2 keep their order, and the two zeros go to the end.
Example 2
Input: nums = [3, 8]
Output: [3, 8]
Explanation: There are no zeros, so nothing moves.
Hints
Approach
Use two indices on the same list. read visits every element, and write marks where the next non-zero value belongs. Everything before write is already final.
- Set
write = 0. - For each
readindex, ifnums[read]is non-zero, swap it withnums[write]and increasewrite. - When the loop ends, every zero has been swapped behind the non-zero values.
Swapping (instead of just copying) means the zeros move to the back as you go, so there is no separate fill step, and the non-zero values keep their order because they are placed in the order they are read.
O(n)Space O(1)class Solution: def moveZeroes(self, nums: list[int]) -> None: write = 0 for read in range(len(nums)): if nums[read] != 0: nums[write], nums[read] = nums[read], nums[write] write += 1Follow-up questions
- Minimise the number of writes to the list.
- Move all values equal to a given
targetto the end instead of zeros.
Frequently asked questions
nums = ... only rebinds the local name to a new list, and the caller's list is unchanged. nums[:] = ... replaces the contents of the existing list, which is what "in place" means.
Yes: copy each non-zero value to nums[write], then fill positions write to the end with zeros afterwards. It does fewer writes when there are many non-zero values at the front, but needs the second pass.
The read/write pointer is the standard way to filter a buffer in place, for example compacting a list of connections by dropping closed ones, or removing empty entries from a batch before sending it, without allocating a second buffer.