
Problem Statement
The task is to rearrange elements within an integer array nums such that all zeros (0s) are moved to the end of the array, while ensuring that the order of the non-zero elements remains unchanged. This operation must be performed directly on the input array, meaning modifications should be done in-place without the aid of creating a duplicate array for processing. This problem tests one's capability to manipulate array indices and understand in-place algorithmic operations efficiently.
Examples
Example 1
Input:
nums = [0,1,0,3,12]
Output:
[1,3,12,0,0]
Example 2
Input:
nums = [0]
Output:
[0]
Constraints
1 <= nums.length <= 104-231 <= nums[i] <= 231 - 1
Approach and Intuition
The main goal is to keep track of where the next non-zero element should be placed in the array. We can achieve this by employing a two-pointer technique:
- One pointer, let's call it
nonZeroIndex, will track the position where the next non-zero element should be placed. - Another pointer will iterate through the array, checking each element.
Breakdown of Algorithm:
- Initialize
nonZeroIndexto zero. This pointer marks the spot where the next non-zero number should be placed in the array. - Iterate over the array with another pointer called
i.- If the element at
i(nums[i]) is non-zero:- Move
nums[i]to the position indicated bynonZeroIndex. - Increment
nonZeroIndex.
- Move
- If the element at
iis zero, do nothing.
- If the element at
- After processing all elements with the loop, all non-zero elements are now at the beginning, in their original relative order. The remainder of the array from
nonZeroIndexto the end should be filled with zeros.
Visual Example:
Consider nums = [0,1,0,3,12]:
- Start with
nonZeroIndex = 0. i = 0→nums[0]is0, do nothing.i = 1→nums[1]is1. Place1atnums[0]and incrementnonZeroIndexto 1.i = 2→nums[2]is0, do nothing.i = 3→nums[3]is3. Place3atnums[1]and incrementnonZeroIndexto 2.i = 4→nums[4]is12. Place12atnums[2]and incrementnonZeroIndexto 3.- Fill remaining places with
0s (fromnums[3]onwards).
Result reflects as [1, 3, 12, 0, 0], matching our expected output with zeros at the end and non-zero elements maintaining their original sequence.
This method ensures in-place rearrangement with minimal space complexity and avoids unnecessary operations.
Solutions
- C++
class Solution {
public:
void shiftZeroes(vector<int>& elements) {
for (int lastNonZeroPos = 0, currIndex = 0; currIndex < elements.size(); currIndex++) {
if (elements[currIndex] != 0) {
swap(elements[lastNonZeroPos++], elements[currIndex]);
}
}
}
};
This solution tackles the problem of moving all the zeroes in an array to the end while maintaining the relative order of other elements. Written in C++, the function shiftZeroes operates directly on the vector of integers provided.
Follow these steps to understand the provided method:
- Initialize two pointers;
lastNonZeroPosfor tracking the position of the last non-zero element found, andcurrIndexto traverse through the array. - Continue iterating through the vector
elementsusingcurrIndex. - Check if the current element is non-zero. If true, it swaps the current element with the element at
lastNonZeroPos, effectively moving the non-zero element to the front of the array. After the swap, incrementlastNonZeroPosto point to the next position. - This approach ensures that all zero elements are pushed towards the end as non-zero elements are collected at the beginning.
- Initialize two pointers;
This method is efficient and maintains a linear time complexity. The use of in-place operations ensures that no additional memory is required, making it space-efficient as well.