DSA patterns

Move Zeroes

easyTwo pointers

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.

  1. Set write = 0.
  2. For each read index, if nums[read] is non-zero, swap it with nums[write] and increase write.
  3. 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.

ComplexityTime O(n)Space O(1)
Python
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 += 1

Follow-up questions

  • Minimise the number of writes to the list.
  • Move all values equal to a given target to 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.