Move All Zeros to the End of an Array
Move all zeros to the end of an array in place, preserving the order of non-zero values.
Keep an `insert` index for the next non-zero slot. Scan the array; whenever you meet a non-zero value, write it at `arr[insert]` and advance `insert`. After the scan, fill positions from `insert` to the end with zeros. This is O(n) time, O(1) space and keeps non-zero order.
Problem Statement
Given an integer array, move every 0 to the end of the array while keeping the
relative order of the non-zero elements unchanged. Modify the array in place.
For example, [0, 1, 0, 3, 12] becomes [1, 3, 12, 0, 0]: the non-zeros stay in
the order 1, 3, 12 and both zeros are pushed to the back.
Input: An integer array arr of length n (n >= 0).
Output: The same array with all zeros moved to the end, non-zero order preserved.
Examples
Input: [0, 1, 0, 3, 12]
Output: [1, 3, 12, 0, 0]1, 3, 12 keep their order at the front; the two zeros go to the end.
Input: [0, 0, 1]
Output: [1, 0, 0]The only non-zero, 1, moves to the front; both zeros follow.
Constraints
0 <= n <= 10^6Must be done in place using O(1) extra space
Think Before You Code
Reveal the questions to ask yourself first
- How can you track where the next non-zero value should be written?
- If you only copy non-zero values forward, what is left in the trailing slots?
- How do you keep the non-zero values in their original relative order?
Hints
Open them one at a time — try after each before revealing the next.
Hint 1
Hint 2
Hint 3
Approach
Reveal the step-by-step approach
Compact the non-zeros to the front, then pad with zeros.
- Set
insert = 0. - For each element
vin order: ifv != 0, writearr[insert] = vand incrementinsert. - When the scan ends,
insertmarks the first trailing slot. Fill indicesinsertthroughn - 1with 0.
Because non-zeros are copied in the order they appear, their relative order is preserved, and the two loops together touch each element a constant number of times.
Dry Run
Walk through the example step by step
Processing [0, 1, 0, 3, 12]:
i | v | action | array after | insert
--+----+-----------------------+------------------+-------
0 | 0 | skip | [0,1,0,3,12] | 0
1 | 1 | arr[0]=1 | [1,1,0,3,12] | 1
2 | 0 | skip | [1,1,0,3,12] | 1
3 | 3 | arr[1]=3 | [1,3,0,3,12] | 2
4 | 12 | arr[2]=12 | [1,3,12,3,12] | 3
pad zeros from index 3 | [1,3,12,0,0] | 3
Solution
Reveal the full Java solution
import java.util.Arrays;
public class MoveZerosToEnd {
public static void moveZeros(int[] arr) {
int insert = 0;
for (int v : arr) {
if (v != 0) {
arr[insert++] = v;
}
}
while (insert < arr.length) {
arr[insert++] = 0;
}
}
public static void main(String[] args) {
int[] a = {0, 1, 0, 3, 12};
moveZeros(a);
System.out.println(Arrays.toString(a)); // [1, 3, 12, 0, 0]
int[] b = {0, 0, 1};
moveZeros(b);
System.out.println(Arrays.toString(b)); // [1, 0, 0]
}
}
The write index insert never runs ahead of the read position, so overwriting
arr[insert] is always safe — that slot has already been read. The first loop
packs the non-zeros; the second loop zero-fills the remainder. Both loops are
linear, giving O(n) time and O(1) extra space.
O(n)Space: O(1)Common Mistakes
- Swapping a zero with the next non-zero on every step, which can disturb the relative order of non-zeros.
- Forgetting the second loop, so old non-zero values linger in the trailing slots.
Edge Cases to Test
- An array of all zeros stays all zeros (insert stays at 0).
- An array with no zeros is returned unchanged.
- An empty array must not throw.
Interview Follow-Ups
- How would you move zeros to the front instead of the end?
- Can you do it with a single pass of swaps while still preserving order?
- How would you generalize this to move every occurrence of a given target value?
Practising for Java interviews?
CodeBegun's Java Full Stack with AI program builds this problem-solving muscle with mentor review and mock interviews.
Explore the Java Full Stack program →