283. Move Zeroes
easyAsked at JPMorganIn-place move every zero to the end of an array while keeping non-zero values in their original order. JPMorgan asks this as a Software Engineer Programme phone-screen warm-up to see whether you reach for two-pointer over-write before allocating a new array.
By Sam K., Founder, InterviewChamp.AI · Last verified
Source citations
Public interview reports confirming this problem appears in JPMorgan loops.
- Glassdoor (2026-Q1)— Recurring JPMorgan SDE phone-screen warm-up in new-grad and lateral reviews.
- LeetCode (2026-Q1)— Tagged JPMorgan on the LeetCode company tag page.
- Reddit r/cscareerquestions (2025-11)— JPMC SWE-I write-up cites Move Zeroes as the array warm-up before a harder follow-up.
Problem
Given an integer array nums, move all 0's to the end of it while maintaining the relative order of the non-zero elements. Note that you must do this in-place without making a copy of the array.
Constraints
1 <= nums.length <= 10^4-2^31 <= nums[i] <= 2^31 - 1
Examples
Example 1
nums = [0,1,0,3,12][1,3,12,0,0]Example 2
nums = [0][0]Approaches
1. Two-pass: copy non-zeros then fill
First pass writes every non-zero to a write-index. Second pass fills [writeIndex..end] with zeros.
- Time
- O(n)
- Space
- O(1)
function moveZeroesTwoPass(nums) {
let w = 0;
for (let i = 0; i < nums.length; i++) {
if (nums[i] !== 0) nums[w++] = nums[i];
}
while (w < nums.length) nums[w++] = 0;
}Tradeoff: Two passes but each is linear and the writes are sequential — cache-friendly. Easier to reason about than the swap version and equally optimal.
2. Single-pass two-pointer swap (optimal in writes)
Maintain a write-pointer for the next non-zero slot. Walk the array; on a non-zero, swap it with nums[writeIndex] and advance writeIndex.
- Time
- O(n)
- Space
- O(1)
function moveZeroes(nums) {
let w = 0;
for (let i = 0; i < nums.length; i++) {
if (nums[i] !== 0) {
[nums[w], nums[i]] = [nums[i], nums[w]];
w++;
}
}
}Tradeoff: Single pass with strictly fewer writes than the two-pass version when zeros are rare (only swap when needed). Preferred on the LeetCode 'follow-up: minimise writes' variant of the question.
JPMorgan-specific tips
JPMorgan interviewers note three signals on this problem: (1) you commit to in-place from the first sentence (do not propose allocating); (2) you mention both the two-pass and the swap version and articulate the write-count difference; (3) you correctly handle the all-zero, all-nonzero, and single-element edge cases without explicit branches.
Common mistakes
- Allocating a new array and returning it — violates the in-place constraint.
- Forgetting that the relative order of non-zero elements must be preserved (sort-based shortcuts break this).
- Off-by-one on the write index — writing beyond the array end when zeros are interleaved.
- Using nums.filter then concat — allocates, fails the constraint, and is slower than the two-pointer.
Follow-up questions
An interviewer at JPMorgan may pivot to one of these next:
- What if the order of non-zero elements does not matter? (Two-pointer from both ends.)
- Move zeros to the front instead of the back.
- Generalise: move every element matching predicate P to the end while preserving the rest's order.
- What if we must minimise the number of writes? (Swap version + skip self-swap.)
Solve it now
Free. No sign-up. Python and JavaScript run instantly in your browser.
FAQ
Why is the swap version sometimes preferred?
When the array is mostly non-zero, the two-pass version writes every element at least once even if the element is already in place. The swap version only writes when nums[i] != nums[w], so it can do far fewer writes in the common case. LeetCode's official follow-up asks specifically to minimise writes.
Does the relative order of zeros matter?
No. The problem only constrains the order of non-zero elements. All zeros are interchangeable, so both approaches above are correct.
Free learning resources
Curated free links for this problem.