How to Move All Zeros to the Beginning of an Array in Java
Moving all zeros to the beginning of an array is the reverse of moving zeros to the end. Although the problem appears similar, the implementation requires a different traversal strategy to preserve the relative order of the non-zero elements.
The most efficient solution uses a reverse two-pointer technique, where the array is scanned from right to left. This approach modifies the original array directly, achieving O(n) time complexity and O(1) extra space.
In this tutorial, you'll learn the optimal in-place solution, understand how it works step by step, and explore the common mistakes to avoid.
Problem Statement
Given the following array:
int[] numbers = {0, 1, 0, 3, 12};
Move all zeros to the beginning while preserving the order of the non-zero elements.
Before
[0, 1, 0, 3, 12]
After
[0, 0, 1, 3, 12]
Adapting the "Move to End" Logic in Reverse
The solution for moving zeros to the end scans the array from left to right and places non-zero elements toward the beginning.
To move zeros to the beginning, simply reverse the direction:
- Scan the array from right to left.
- Place non-zero elements from the end toward the beginning.
- Finally, fill the remaining positions at the front with zeros.
This preserves the relative order of the non-zero elements while avoiding any extra array.
Method: Reverse Two-Pointer In-Place Technique (Optimal)
Example
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] numbers = {0, 1, 0, 3, 12};
int insertPosition = numbers.length - 1;
for (int i = numbers.length - 1; i >= 0; i--) {
if (numbers[i] != 0) {
numbers[insertPosition] = numbers[i];
insertPosition--;
}
}
while (insertPosition >= 0) {
numbers[insertPosition] = 0;
insertPosition--;
}
System.out.println(Arrays.toString(numbers));
}
}
Output
[0, 0, 1, 3, 12]
Explanation
The algorithm performs two passes:
- Traverse the array from right to left and move every non-zero element toward the end.
- Fill all remaining positions at the beginning with zeros.
This approach modifies the original array directly without allocating additional memory.
Time Complexity: O(n)
Space Complexity: O(1)
Step-by-Step Explanation
Consider the array:
[0, 1, 0, 3, 12]
Initially:
insertPosition = 4
Step 1
i = 4
numbers[4] = 12
Move it to position 4.
[0, 1, 0, 3, 12]
Update:
insertPosition = 3
Step 2
i = 3
numbers[3] = 3
Move it.
[0, 1, 0, 3, 12]
Update:
insertPosition = 2
Step 3
i = 2
numbers[2] = 0
Skip it.
Step 4
i = 1
numbers[1] = 1
Move it to position 2.
[0, 1, 1, 3, 12]
Update:
insertPosition = 1
Step 5
i = 0
numbers[0] = 0
Skip it.
Step 6
Fill the remaining positions with zeros.
numbers[1] = 0
numbers[0] = 0
Final array:
[0, 0, 1, 3, 12]
Internal Working
Initial array:
[0, 1, 0, 3, 12]
After moving non-zero elements:
[0, 1, 1, 3, 12]
Notice that one duplicate value temporarily exists because the unused positions haven't been overwritten yet.
After filling zeros:
[0, 0, 1, 3, 12]
Only two integer variables (i and insertPosition) are used throughout the algorithm.
Real-Life Analogy
Imagine a conveyor belt carrying filled and empty boxes.
This time, you start walking from the end of the conveyor belt toward the beginning.
Whenever you find a filled box, you slide it into the next available position at the back.
After reaching the beginning, every remaining position naturally belongs to an empty box, so you mark them as empty.
This mirrors the reverse two-pointer algorithm exactly.
Best Practices
- Use the reverse two-pointer technique for an optimal in-place solution.
- Verify that the relative order of non-zero elements remains unchanged.
- Test arrays containing only zeros.
- Test arrays containing no zeros.
- Test single-element and empty arrays.
- Avoid creating another array unless modifying the original array is not allowed.
Common Mistakes
1. Using the "Move to End" Algorithm Without Modification
The traversal direction must be reversed.
Scanning from left to right produces incorrect results for this problem.
2. Not Preserving the Order of Non-Zero Elements
Changing the order of non-zero values produces an incorrect solution for most interview questions.
3. Off-by-One Errors
Incorrect:
for (int i = numbers.length; i >= 0; i--)
Correct:
for (int i = numbers.length - 1; i >= 0; i--)
4. Using an Unnecessary Three-Step Reverse Approach
Although reversing the array, applying the "move to end" algorithm, and reversing again works, it performs more operations than the direct reverse two-pointer solution.
Expert Tips
- Many array algorithms have a mirror-image solution that simply reverses the traversal direction.
- The reverse two-pointer pattern is useful for problems involving processing elements from the end of an array.
- This same approach can move any chosen value—not just zero—to the beginning.
- Understanding why the algorithm preserves the order of non-zero elements is more valuable than memorizing the code.
Comparison Table
| Method | Time Complexity | Space Complexity | Preserves Order? |
|---|---|---|---|
| Reverse Two-Pointer Technique | O(n) | O(1) | ✅ Yes (Optimal) |
| Reverse Array → Move to End → Reverse Again | O(n) | O(1) | ✅ Yes, but requires three passes |
Frequently Asked Questions
1. How is moving zeros to the beginning different from moving them to the end?
Moving zeros to the beginning requires scanning the array from right to left while writing non-zero elements toward the end.
2. Does this method preserve the order of non-zero elements?
Yes. The reverse two-pointer technique preserves the original relative order of all non-zero elements.
3. Can I reverse the array, move zeros to the end, and reverse it again?
Yes. That approach works but requires three passes through the array, making it less efficient than directly using the reverse two-pointer technique.
4. What happens if the array contains no zeros?
The algorithm copies each element back to its original position, and the zero-filling loop performs no work.
5. What is the time and space complexity?
The optimal solution runs in O(n) time and uses O(1) extra space.
6. Can this technique move another value to the beginning?
Yes. Simply replace the zero comparison with the value you want to move.
7. Is this problem asked in coding interviews?
Yes. Although less common than moving zeros to the end, it is a popular follow-up question that tests whether you truly understand the two-pointer technique.
8. How can I verify my implementation?
Test your solution with:
- Arrays containing only zeros
- Arrays containing no zeros
- Zeros at the beginning
- Zeros at the end
- Zeros scattered throughout the array
In every case, the non-zero elements should remain in their original order.