Problem Statement
Given an integer array nums, move every 0 to the end of the array.
Relative order of all non-zero values must remain unchanged.
The final array contains all non-zero values first in original order, followed by all zeros.
Example 1
Input: nums = [0, 1, 0, 3, 12]
Output: [1, 3, 12, 0, 0]
Explanation: Non-zero values 1, 3, and 12 keep original order. Both zeros move to the end.
Example 2
Input: nums = [0, 0, 1]
Output: [1, 0, 0]
Explanation: Value 1 moves to the front. Two zeros occupy the last two positions.
Example 3
Input: nums = [4, 5, 0, 0, 6]
Output: [4, 5, 6, 0, 0]
Explanation: Non-zero values 4, 5, and 6 keep original order. Zeros shift to the end.
Brute Force Approach
A helper array makes order preservation straightforward.
First, every non-zero value is copied from left to right. Since the values are collected in their original traversal order, their relative order remains unchanged.
Afterward, enough zeroes are added to restore the original array length, and the completed arrangement is copied back into nums.
Algorithm
Create an empty helper array
temp, which will store the elements in their required final order without modifyingnumsduring traversal.Traverse
numsfrom left to right and append every non-zero value totemp. Since they are added in traversal order, their relative order remains unchanged.Append
0s untiltempcontains the same number of elements asnums, filling the positions left after collecting all non-zero values.Copy every value from
tempback into the corresponding position ofnumsso that the original array receives the rearranged order.
Dry Run
Move Zeroes to End Brute Force Dry Run.png
Solution
#include <bits/stdc++.h>using namespace std;class Solution {public: void moveZeroes(vector<int>& nums) { int n = nums.size(); vector<int> temp; /* * Collect non-zero values first * to preserve their original order. */ for (int num : nums) { if (num != 0) { temp.push_back(num); } } /* * Fill the remaining positions * with zeroes. */ while (temp.size() < n) { temp.push_back(0); } // Copy the final arrangement back into nums. for (int index = 0; index < n; index++) { nums[index] = temp[index]; } }};int main() { vector<int> nums = {0, 1, 0, 3, 12}; Solution solution; solution.moveZeroes(nums); for (int num : nums) { cout << num << " "; } return 0;}Complexity Analysis
Time Complexity: O(N), where N represents the array size. Linear traversals collect the non-zero values, append the required zeroes, and copy the final arrangement back.
Space Complexity: O(N), because the helper array may store all N elements.
Better Approach
The helper array can be removed by treating the front part of nums as the destination for non-zero values.
A variable insertPosition marks the next index where a non-zero value should be placed. Every non-zero value is written there, and the position advances.
Once all non-zero values have been compacted at the front, the remaining positions are filled with zeroes.
Algorithm
Initialize
insertPositionwith0, where it represents the next position at which a non-zero value should be placed.Traverse
numsfrom left to right so that non-zero values are processed in their original order.Whenever
nums[index]is non-zero, write it atnums[insertPosition]and incrementinsertPosition. This compacts all non-zero values toward the beginning without changing their relative order.After the traversal, every position before
insertPositioncontains the required non-zero values.Fill all positions from
insertPositionto the last index with0, since these are the positions remaining after the non-zero section.
Dry Run
Move Zeroes to End Better Approach Dry Run.png
Solution
#include <bits/stdc++.h>using namespace std;class Solution {public: void moveZeroes(vector<int>& nums) { int n = nums.size(); int insertPosition = 0; /* * Place non-zero values at the front * in the same order they appear. */ for (int index = 0; index < n; index++) { // Only non-zero values belong in the front section. if (nums[index] != 0) { nums[insertPosition] = nums[index]; insertPosition++; } } /* * Positions left after compaction * must contain zeroes. */ while (insertPosition < n) { nums[insertPosition] = 0; insertPosition++; } }};int main() { vector<int> nums = {0, 1, 0, 3, 12}; Solution solution; solution.moveZeroes(nums); for (int num : nums) { cout << num << " "; } return 0;}Complexity Analysis
Time Complexity: O(N), where N represents the array size. One traversal places non-zero values, and another traversal fills the remaining positions with zeroes.
Space Complexity: O(1), because the array is modified using only insertPosition and loop variables.
Optimal Approach
The array can be rearranged during a single traversal using two pointers.
zeroPosition marks the next front position that should contain a non-zero value. The current pointer scans the array from left to right.
Whenever a non-zero value appears, it is swapped with the value at zeroPosition. Since non-zero values are processed from left to right, their relative order remains unchanged. Zeroes are gradually moved behind the non-zero section.
Algorithm
Initialize
zeroPositionwith0, where it represents the next front position that should contain a non-zero value.Traverse the array from left to right using
current, allowing non-zero values to be handled in their original order.If
nums[current]is non-zero, swap it withnums[zeroPosition]. When zeros have already been encountered, this places the current non-zero value into the earliest available position before them.Increment
zeroPositionafter every non-zero value, so it continues to point to the next position available for another non-zero element.If the current value is
0, leave it unchanged. A later non-zero value will automatically swap into that position when required.After the traversal, the non-zero values appear first in their original order, while all zeros are pushed to the end.
Dry Run
Move Zeroes to End Optimal Dry Run.png
Solution
#include <bits/stdc++.h>using namespace std;class Solution {public: void moveZeroes(vector<int>& nums) { int n = nums.size(); int zeroPosition = 0; for (int current = 0; current < n; current++) { /* * A non-zero value belongs at the * next available front position. */ if (nums[current] != 0) { swap(nums[current], nums[zeroPosition]); zeroPosition++; } } }};int main() { vector<int> nums = {0, 1, 0, 3, 12}; Solution solution; solution.moveZeroes(nums); for (int num : nums) { cout << num << " "; } return 0;}Complexity Analysis
Time Complexity: O(N), where N represents the array size. A single traversal processes every element exactly once.
Space Complexity: O(1), because only the two pointer variables require auxiliary storage.
Interview follow-up Questions
The problem requires a stable rearrangement. A sequence such as [4, 0, 2] must become [4, 2, 0], not [2, 4, 0].
Be the first to add a comment.