Java Program to Move All Zeros to End of Array (In Place)

Moving all zeros to the end of an array is a common Java programming interview question. The goal is to rearrange the array so that every zero appears at the end while keeping the nonzero elements in their original order.

For example, consider the array {0, 1, 0, 3, 12}. After moving the zeros, the array becomes {1, 3, 12, 0, 0}. The order of the nonzero elements remains unchanged.

This problem is useful for learning array traversal, conditional statements, and the two-pointer technique. It also demonstrates how to modify an array in place without allocating another array.

In Java, you can solve this problem efficiently using a single traversal followed by filling the remaining positions with zeros. Another approach uses two pointers to swap nonzero elements into their correct positions.

In this tutorial, I will explain both approaches with complete Java programs, expected output, step-by-step examples, and time and space complexity analysis.

Understanding the Move Zeros Problem

Consider the following integer array:

int[] numbers = {0, 1, 0, 3, 12};

The array contains three nonzero elements and two zeros.

The expected result is:

[1, 3, 12, 0, 0]

The solution must satisfy three conditions:

  1. Move every zero to the end of the array.
  2. Preserve the relative order of all nonzero elements.
  3. Modify the original array without creating another array.

The third requirement makes this an in-place array manipulation problem.

More Examples

Input Array Expected Output
{0, 1, 0, 3, 12} {1, 3, 12, 0, 0}
{1, 0, 2, 0, 3} {1, 2, 3, 0, 0}
{0, 0, 1, 2} {1, 2, 0, 0}
{1, 2, 3} {1, 2, 3}
{0, 0, 0} {0, 0, 0}

Method 1: Move All Zeros to the End Using Two Pointers

The most straightforward solution uses two indexes named read and write.

The read pointer examines every element. The write pointer tracks the position where the next nonzero element should be placed.

The algorithm works in two stages:

  1. Copy all nonzero elements toward the beginning of the original array.
  2. Fill the remaining positions with zeros.

Because the nonzero elements are processed from left to right, their relative order is preserved.

Complete Java Program

Create a Java class named MoveZerosToEndExample and add the following code:

import java.util.Arrays;
import java.util.Objects;

public class MoveZerosToEndExample {

    public static void main(String[] args) {

        int[] numbers = {0, 1, 0, 3, 12};

        System.out.println("Original array: "
                + Arrays.toString(numbers));

        moveZerosToEnd(numbers);

        System.out.println("Array after moving zeros: "
                + Arrays.toString(numbers));
    }

    /**
     * Moves all zeros to the end of an integer array.
     *
     * The relative order of nonzero elements is preserved.
     * The input array is modified in place.
     *
     * @param numbers the array to modify
     * @throws NullPointerException if the array is null
     */
    public static void moveZerosToEnd(int[] numbers) {

        Objects.requireNonNull(numbers, "Array must not be null");

        int write = 0;

        // Move nonzero elements toward the beginning.
        for (int read = 0; read < numbers.length; read++) {

            if (numbers[read] != 0) {
                numbers[write] = numbers[read];
                write++;
            }
        }

        // Replace the remaining positions with zeros.
        while (write < numbers.length) {
            numbers[write] = 0;
            write++;
        }
    }
}

Output

Original array: [0, 1, 0, 3, 12]
Array after moving zeros: [1, 3, 12, 0, 0]

How Does the Program Work?

The method begins by checking that the input array is not null.

It then initializes the write pointer:

int write = 0;

This pointer identifies where the next nonzero element should be stored.

Step 1: Traverse the Array

The read pointer visits every element:

for (int read = 0; read < numbers.length; read++)

When the program finds a nonzero value, it copies that value to the position identified by write.

if (numbers[read] != 0) {
    numbers[write] = numbers[read];
    write++;
}

Zeros are skipped during this stage.

Step 2: Fill Remaining Positions with Zeros

After the first loop, all nonzero elements are grouped at the beginning of the array.

The write pointer now identifies the first position that should contain zero.

The second loop fills all remaining positions:

while (write < numbers.length) {
    numbers[write] = 0;
    write++;
}

The result is an array in which all zeros appear at the end.

Step-by-Step Dry Run

Consider the input array:

[0, 1, 0, 3, 12]

Initially:

write = 0

The program examines each element and moves nonzero values toward the beginning.

Read Index Current Value Action Write After Step
0 0 Skip zero 0
1 1 Write 1 at index 0 1
2 0 Skip zero 1
3 3 Write 3 at index 1 2
4 12 Write 12 at index 2 3

After the first loop, the first three positions contain the nonzero values:

[1, 3, 12, 3, 12]

The values in the last two positions are leftover values and must be replaced with zeros.

The second loop fills those positions:

[1, 3, 12, 0, 0]

The array is now rearranged correctly.

Method 2: Move All Zeros Using Swapping

You can also solve this problem by swapping nonzero elements with earlier zero positions.

This approach uses two pointers:

  • read examines the array elements.
  • write identifies the next position for a nonzero element.

Whenever the program finds a nonzero element, it swaps that element with the value at the write position.

If both pointers refer to the same position, no swap is necessary.

Java Program

import java.util.Arrays;
import java.util.Objects;

public class MoveZerosUsingSwap {

    public static void main(String[] args) {

        int[] numbers = {0, 1, 0, 3, 12};

        System.out.println("Original array: "
                + Arrays.toString(numbers));

        moveZerosToEnd(numbers);

        System.out.println("Array after moving zeros: "
                + Arrays.toString(numbers));
    }

    /**
     * Moves zeros to the end by swapping elements in place.
     *
     * Nonzero elements retain their relative order.
     *
     * @param numbers the array to modify
     */
    public static void moveZerosToEnd(int[] numbers) {

        Objects.requireNonNull(numbers, "Array must not be null");

        int write = 0;

        for (int read = 0; read < numbers.length; read++) {

            if (numbers[read] != 0) {

                // Swap only when the positions differ.
                if (read != write) {
                    int temp = numbers[read];
                    numbers[read] = numbers[write];
                    numbers[write] = temp;
                }

                write++;
            }
        }
    }
}

Output

Original array: [0, 1, 0, 3, 12]
Array after moving zeros: [1, 3, 12, 0, 0]

Explanation

The program uses the read pointer to examine each element.

When a nonzero value is found, the program swaps it with the element at the write position.

The write pointer advances only after processing a nonzero element.

Because the algorithm always moves the next nonzero value into the next available position, the original order of nonzero values is preserved.

Unlike the first method, this approach does not require a separate loop to fill the end of the array with zeros.

The swaps move zeros toward the end as the nonzero values are moved forward.

Method 3: Move Zeros Using an Extra Array

Another approach is to create a new array and copy all nonzero elements into it.

In Java, a newly created int[] is automatically initialized with zeros.

Therefore, after copying the nonzero values to the beginning of the new array, the remaining positions already contain zeros.

This approach is easy to understand, but it requires additional memory and does not modify the original array in place.

Java Program

import java.util.Arrays;
import java.util.Objects;

public class MoveZerosUsingNewArray {

    public static void main(String[] args) {

        int[] numbers = {0, 1, 0, 3, 12};

        int[] result = moveZerosToEnd(numbers);

        System.out.println("Original array: "
                + Arrays.toString(numbers));

        System.out.println("Array after moving zeros: "
                + Arrays.toString(result));
    }

    /**
     * Returns a new array with all zeros moved to the end.
     *
     * @param numbers the source array
     * @return a new array with nonzero values first
     */
    public static int[] moveZerosToEnd(int[] numbers) {

        Objects.requireNonNull(numbers, "Array must not be null");

        int[] result = new int[numbers.length];

        int write = 0;

        // Copy nonzero values into the new array.
        for (int number : numbers) {

            if (number != 0) {
                result[write] = number;
                write++;
            }
        }

        // Unused positions remain zero by default.
        return result;
    }
}

Output

Original array: [0, 1, 0, 3, 12]
Array after moving zeros: [1, 3, 12, 0, 0]

This approach preserves the original array because it returns a separate array containing the rearranged elements.

How to Run the Java Programs

You can run these examples using IntelliJ IDEA, Eclipse, Visual Studio Code, or the command line.

To run the first example:

  1. Install a Java Development Kit (JDK).
  2. Create a file named MoveZerosToEndExample.java.
  3. Copy the code from Method 1 into the file.
  4. Open a terminal in the folder containing the file.
  5. Compile and execute the program:
javac MoveZerosToEndExample.java
java MoveZerosToEndExample

For the other programs, save each class in a file matching its public class name.

Important Edge Cases

The algorithm should handle arrays with no zeros, only zeros, negative numbers, and empty arrays.

Input Array Expected Output
{0, 1, 0, 3, 12} {1, 3, 12, 0, 0}
{0, 0, 0} {0, 0, 0}
{1, 2, 3} {1, 2, 3}
{0, 0, 1, 2} {1, 2, 0, 0}
{1, 2, 0, 0} {1, 2, 0, 0}
{-1, 0, -2, 0, 3} {-1, -2, 3, 0, 0}
{0} {0}
{} {}

Time and Space Complexity

Let n represent the number of elements in the array.

Approach Time Complexity Extra Space
Two pointers with zero filling O(n) O(1)
Two pointers with swapping O(n) O(1)
Extra array O(n) O(n)

Both two-pointer approaches process the array in linear time and use only a constant amount of additional memory.

The extra-array approach also takes linear time, but it allocates another array containing n elements.

Common Mistakes When Moving Zeros to the End

1. Changing the Order of Nonzero Elements

The problem usually requires preserving the relative order of nonzero values.

For example, the input {0, 3, 0, 1, 2} should become {3, 1, 2, 0, 0}.

Moving values without considering their order can produce an incorrect result.

2. Forgetting to Fill the Remaining Positions with Zeros

In the first approach, copying nonzero elements toward the beginning may leave old values in later positions.

The second loop is necessary to replace those remaining values with zeros.

3. Incrementing the Write Pointer for Every Element

The write pointer should advance only when a nonzero element is processed.

Incrementing it for zeros would prevent the algorithm from grouping nonzero values at the beginning.

4. Creating an Extra Array When In-Place Modification Is Required

If an interview question specifically asks for an in-place solution, creating a new array does not satisfy that requirement.

Use one of the two-pointer approaches instead.

5. Ignoring Empty or Null Arrays

An empty array does not require any changes.

A null array cannot be processed. The examples use Objects.requireNonNull() to reject null input explicitly.

Frequently Asked Questions

How do you move all zeros to the end of an array in Java?

Use a write pointer to place nonzero elements at the beginning of the array. After processing all elements, fill the remaining positions with zeros.

Can I move zeros to the end without using another array?

Yes. The two-pointer approach modifies the original array and uses O(1) extra space.

How do you preserve the order of nonzero elements?

Process the array from left to right and place each nonzero element in the next available position. This preserves their relative order.

What is the time complexity of moving zeros to the end?

The two-pointer approach takes O(n) time because each array element is examined once.

Does the algorithm work with negative numbers?

Yes. The algorithm moves only values equal to zero. Negative and positive nonzero values retain their relative order.

Which approach is best for Java coding interviews?

The two-pointer approach is generally the best solution. It runs in linear time, uses constant extra space, and preserves the order of nonzero elements.

Conclusion

In this tutorial, you learned how to move all zeros to the end of an array in Java using two pointers, swapping, and an additional array.

The two-pointer approach is the most practical solution when you need to modify the original array without allocating extra storage. It moves nonzero elements toward the beginning and places zeros at the end while preserving the order of the remaining elements.

The swapping approach provides another in-place solution and avoids a separate zero-filling loop. The extra-array approach is useful when the original array must remain unchanged.

For Java coding interviews, I recommend practicing the two-pointer solution first. Once you understand how the read and write pointers work, try related problems such as moving negative numbers to one side, removing a specific value from an array, and partitioning an array based on a condition.

Official Java Documentation

For more information about Java arrays and the APIs used in this tutorial, refer to the following official Oracle documentation:

Continue Learning with Java Guides

Want to take your programming skills to the next level? Explore my practical Udemy courses on Java, Spring Boot, Microservices, Full-Stack Development, Docker, and Generative AI. You can also follow my structured learning roadmaps to become a professional developer.

By Ramesh Fadatare - Udemy Instructor Partner

Comments