Separating zeroes from non-zeroes is easy. Two constraints make the problem more than that. First, the relative order of the non-zero elements must be preserved. Second, the work has to happen in-place, with no second array.
Once every non-zero element is in its correct position, the zeroes can only fall into the remaining positions at the end. So the problem reduces to placing the non-zero elements in order, at the front, without using extra space.
1 <= nums.length <= 10^4 → With n up to 10,000, an O(n) single pass handles the input comfortably, so there is no reason to settle for an O(n^2) shifting solution.-2^31 <= nums[i] <= 2^31 - 1 → Values span the full signed 32-bit range and can be negative. The condition that matters is nums[i] != 0, not nums[i] > 0.in-place → The array must be rearranged within its own storage. A solution that allocates an O(n) array violates this, which is what the follow-up about minimizing operations is pointing toward.Build the answer in a second array: walk through nums, append each non-zero element to the next slot of result, and leave the remaining slots as zero. Then copy result back over nums. This ignores the in-place requirement, so it does not satisfy the follow-up, but it separates the two concerns (order of non-zeroes, position of zeroes) and makes the logic easy to follow before optimizing for space.
result of the same size as nums.nums. For each non-zero element, place it at the next available position in result.result are already zero (default values).result back into nums.Input:
After the first pass (collect non-zeroes into result):
Finally, we copy result back into nums:
This is correct but allocates a second array of size n, which the in-place requirement rules out. The next approach removes that array by placing non-zero elements directly into the front of the original array as it scans.
A single pointer insertPos marks where the next non-zero element belongs. Scanning the array with index i, every time nums[i] is non-zero we swap it into nums[insertPos] and advance insertPos. Zeroes are skipped, so they accumulate ahead of insertPos and are pushed toward the end by later swaps.
The loop keeps two invariants. Everything in nums[0 .. insertPos - 1] is a non-zero element in its original relative order, and everything in nums[insertPos .. i - 1] is a zero. Because insertPos <= i, the slot at nums[insertPos] in a swap is either one of those skipped zeroes or i itself, so a non-zero element is never overwritten and the relative order is preserved.
insertPos = 0 to track the next position for a non-zero element.i from 0 to n - 1.nums[i] is not zero, swap nums[i] with nums[insertPos], then increment insertPos.insertPos, temp). No additional data structures.Approach 2 swaps on every non-zero element, including when i == insertPos and the element is already in place. In an array like [1, 2, 3, 0, 0], the first three iterations swap each element with itself, three wasted writes.
This version writes only when i != insertPos. When a non-zero element is already at its target slot, it advances insertPos without touching the array. The follow-up asks to minimize operations, and this is the gain: the array is modified only for non-zero elements that have to move, so on inputs with few zeroes most iterations do no writes at all.
insertPos = 0.i.nums[i] is not zero:i != insertPos, swap nums[i] with nums[insertPos].insertPos.