top of page

Move Zeroes – A Warm‑Up

  • mosesg1123
  • Apr 15
  • 3 min read

Updated: Apr 22

Let’s walk through one of the classic warm-up problems you might face in a coding interview or on the job: moving all the zeroes in an array to the end, without disrupting the order of the other elements. It’s deceptively simple but tests some important concepts like in-place modification, two-pointer strategies, and maintaining state. It also mirrors real-world issues—like optimizing memory while cleaning up or transforming data.


Problem Statement

Given an integer array nums, move all 0 values to the end of the array in-place, maintaining the relative order of the non-zero elements.

  • Do this with minimal operations.

  • Do not return a new array—modify the input array directly.

  • Extra space is limited to O(1).


1. Clarify Requirements Before Jumping Into Code

Start with a few clarifying questions to make sure we’re solving the right problem:

  • Can I use another array? No, must modify the array in place.

  • What counts as “in place”? Temporary variables (like a couple of pointers) are okay; no copying the whole array.

  • Should I maintain the order of non-zero elements? Yes.

  • What’s allowed in terms of element types? All integers, including negative numbers and zeroes.

Okay, good to go.


2. Identify the Category of the Question

This is a classic array manipulation problem. I immediately think of two-pointer or slow/fast pointer strategies—common patterns when I need to reorganize elements while preserving some relative order. Since it requires in-place changes and zero extra space, it’s less about fancy data structures and more about smart indexing.


3. Consider a Brute‑Force Approach to Understand the Problem

Let’s start simple. What if I just pulled all the non-zero values into a new array and then added the right number of zeroes at the end?

non_zeros = [x for x in nums if x != 0]
zero_count = len(nums) - len(non_zeros)
result = non_zeros + [0] * zero_count

Looks easy, and it works. But we’re creating a new array—not in place. That breaks the constraints. It’s O(n) time, O(n) space. So it’s a good start for understanding, but we can’t submit this in an interview.


4. Brainstorm More Solutions

How can I do this in place?

One option is to use a write pointer that tracks the position to place the next non-zero:

  • Iterate through the array.

  • For each non-zero, write it to the write pointer’s position and increment the pointer.

  • After the pass, fill the remaining slots with zeroes.

That keeps the relative order and overwrites the array directly. O(n) time, O(1) space. Sounds promising.

I could also consider swapping, but that might disrupt the relative order of the non-zero elements unless I’m very careful. That's unnecessarily complicated and probably not the best fit here.


5. Discuss Trade‑Offs Between Your Solutions

Approach

Time

Space

Pros

Cons

Brute-force (new array)

O(n)

O(n)

Simple, readable

Not in-place, violates rules

Two-pointer (write index)

O(n)

O(1)

In-place, efficient

Slightly more complex logic

We’re going with the two-pointer solution.


6. Write Pseudocode to Structure Your Thoughts

function moveZeroes(nums):
    write = 0

    for read from 0 to length(nums) - 1:
        if nums[read] != 0:
            nums[write] = nums[read]
            write += 1

    for i from write to length(nums) - 1:
        nums[i] = 0

7. Consider Edge Cases

  • Empty array ([]) → Should remain empty.

  • All zeroes ([0, 0, 0]) → Should stay the same.

  • No zeroes ([1, 2, 3]) → Should not change.

  • Zeroes at the start ([0, 0, 1, 2]) → Non-zeroes move forward, zeroes shift to end.

  • Interleaved zeroes ([0, 1, 0, 2, 3]) → Non-zeroes move to front in order, zeroes go to back.


8. Write Full Code Syntax

def move_zeroes(nums):
    write = 0

    for read in range(len(nums)):
        if nums[read] != 0:
            nums[write] = nums[read]
            write += 1

    while write < len(nums):
        nums[write] = 0
        write += 1

9. Test Your Code

nums = [0, 1, 0, 3, 12]
move_zeroes(nums)
assert nums == [1, 3, 12, 0, 0]

nums = [1, 2, 3]
move_zeroes(nums)
assert nums == [1, 2, 3]

nums = [0, 0, 0]
move_zeroes(nums)
assert nums == [0, 0, 0]

nums = []
move_zeroes(nums)
assert nums == []

nums = [0, 0, 1]
move_zeroes(nums)
assert nums == [1, 0, 0]

print("All tests passed!")

10. Key Lessons to Remember for Future Questions

  • In-Place Doesn’t Mean No Variables: You can usually use a few extra variables, just don’t allocate new collections.

  • Two-Pointer Is Powerful: When reordering elements, try a read/write or fast/slow pointer approach.

  • Brute Force Helps You Think: Even if it’s not the final answer, a brute-force idea can help reveal a pattern.


This one’s a classic for a reason. Once you’ve got this pattern down, you’re better prepared for all kinds of in-place array challenges.

Recent Posts

See All
Non-Overlapping Intervals

Learn how to solve the Non-Overlapping Intervals coding problem to prepare for your next technical interview!

 
 
 
Merge Intervals

"Merge Intervals" is one of those classic algorithm problems that shows up frequently in technical interviews. It's a great test of your...

 
 
 
Jump Game II

Jump Game II is a classic follow-up to the original Jump Game problem. It’s not just about whether you can reach the end... now you have to do it in the fewest jumps possible! That small change turns

 
 
 

Comments


Drop Me a Line, Let Me Know What You Think

Thanks for submitting!

© 2023 by Train of Thoughts. Proudly created with Wix.com

bottom of page