DEV Community

Cover image for Move Zeroes to the End of an Array: A Practical Guide
Rathod Ketan
Rathod Ketan

Posted on

Move Zeroes to the End of an Array: A Practical Guide

Imagine this: You’re tasked with cleaning up a warehouse. Among the clutter, there are important items mixed with empty boxes. Your job? Push all the empty boxes (zeroes) to the far corner while keeping the other items in the same order. Sounds simple? Well, this common programming problem operates on the same principle: moving all zeroes in an array to its end while preserving the relative order of other elements.

In this guide, we’ll explore not just the "how" but the "why" behind solving this classic problem.

Understanding the Problem

The challenge is to transform an input array like [0, 1, 0, 3, 12] into [1, 3, 12, 0, 0]. Notice how:

All non-zero elements maintain their original order.
Zeroes are pushed to the end without rearranging other elements.
This problem is a favourite in coding interviews because it tests your understanding of array manipulation and optimisation.

A Naïve Approach: The Warehouse Analogy

Imagine walking through the warehouse, picking up empty boxes one by one, and moving them to the corner. In programming terms, this would involve creating a new array:

Traverse the array to copy non-zero elements into a new list.
Append zeroes to the end of this list.

Here’s what it looks like in code:

def move_zeroes_naive(nums):
    result = [x for x in nums if x != 0]  # Gather non-zero elements
    result.extend([0] * nums.count(0))   # Append zeroes
    return result

nums = [0, 1, 0, 3, 12]
print(move_zeroes_naive(nums))  # Output: [1, 3, 12, 0, 0]
Enter fullscreen mode Exit fullscreen mode

While this approach works, it uses extra space, making it less efficient for large datasets.

The Optimised Solution: Two-Pointer Technique

To truly optimise, let’s use a two-pointer approach. Think of it like reorganising the warehouse in one pass:

  • Pointer i scans each item in the array.
  • Pointer last_non_zero_found_at keeps track of where the next non-zero element should go.

Here’s the algorithm in action:

def move_zeroes(nums):
    last_non_zero_found_at = 0

    # Move non-zero elements to the front
    for i in range(len(nums)):
        if nums[i] != 0:
            nums[last_non_zero_found_at], nums[i] = nums[i], nums[last_non_zero_found_at]
            last_non_zero_found_at += 1

nums = [0, 1, 0, 3, 12]
move_zeroes(nums)
print(nums)  # Output: [1, 3, 12, 0, 0]

Enter fullscreen mode Exit fullscreen mode

Why This Approach is Better

  1. In-Place Operation: No extra memory is used, making it ideal for memory-constrained environments.
  2. Efficient: With a time complexity of O(n), the array is processed in a single traversal.
  3. Real-World Use: Mimics practical scenarios where optimised solutions are necessary.

Breaking Down the Algorithm

Let’s visualise how the array changes step by step:

Input: [0, 1, 0, 3, 12]

  1. Initial State: last_non_zero_found_at = 0
  2. Iteration 1 (i=0): No change as nums[0] is zero.
  3. Iteration 2 (i=1): Swap nums[0] and nums[1] → [1, 0, 0, 3, 12]. Update last_non_zero_found_at = 1.
  4. Iteration 3 (i=2): No change as nums[2] is zero.
  5. Iteration 4 (i=3): Swap nums[1] and nums[3] → [1, 3, 0, 0, 12]. Update last_non_zero_found_at = 2.
  6. Iteration 5 (i=4): Swap nums[2] and nums[4] → [1, 3, 12, 0, 0].

Output: [1, 3, 12, 0, 0]

Edge Cases to Consider

When solving this problem, ensure your code handles the following scenarios:

  1. All Zeroes: Input [0, 0, 0] → Output [0, 0, 0].
  2. No Zeroes: Input [1, 2, 3] → Output [1, 2, 3].
  3. Empty Array: Input [] → Output [].

Practical Applications

You might wonder, why move zeroes in the first place? Here’s why:

  1. Database Queries: Cleaning up data where zero represents null or missing values.
  2. Gaming: Rearranging scores or inventories dynamically during gameplay.
  3. Data Compression: Optimising storage by segregating irrelevant values.

Conclusion

In solving the "move zeroes to the end" problem, you’ve tackled more than just a coding challenge. You’ve gained insights into array manipulation, efficiency, and the elegance of simple logic.

By mastering techniques like the two-pointer approach, you’re not just solving interview problems—you’re preparing for real-world scenarios where performance and clarity are paramount.

So, next time you encounter a cluttered "warehouse," you’ll know exactly how to organise it efficiently!

Call-to-Action

Did you find this guide helpful? Check out more problem-solving techniques and optimised algorithms on interviewspreparation.com. Let’s master coding, one problem at a time!

Top comments (1)

Collapse
 
rk042 profile image
Rathod Ketan

Follow For More Interview Questions.