Given two sorted integer arrays nums1 and nums2, along with integers m and n, merge nums2 into nums1 so that nums1 becomes one sorted array.
The first
mpositions ofnums1contain valid sorted elements.The last
npositions ofnums1are reserved for the merge and should not be considered part of the initial data.nums2containsnsorted elements.
Modify nums1 in place so that it contains all m + n elements in non-decreasing order.
Example 1
Input: nums1 = [1, 2, 3, 0, 0, 0], m = 3, nums2 = [2, 5, 6], n = 3
Output: [1, 2, 2, 3, 5, 6]
Explanation: The valid elements of nums1 are [1, 2, 3] and nums2 is [2, 5, 6]. After merging, nums1 becomes [1, 2, 2, 3, 5, 6].
Example 2
Input: nums1 = [1], m = 1, nums2 = [], n = 0
Output: [1]
Explanation: nums2 is empty, so nums1 remains unchanged.
Brute Force Approach
The reserved positions at the end of nums1 provide enough space to copy all elements from nums2.
After copying, all required values are present in nums1, but their combined order may be incorrect. Sorting the complete array gives the required merged result.
Algorithm
Return immediately when
n == 0becausenums1already contains the final sorted array.Traverse
nums2and copy each value into the reserved portion ofnums1, beginning from indexm.After copying, all
m + nrequired elements are present insidenums1.Sort the complete
nums1array in non-decreasing order so the elements from both arrays appear in their correct positions.Retain the sorted
nums1as the final merged array.
Dry Run
Merge Two Sorted Arrays Brute Force Approach Dry Run.png
Solution
#include <bits/stdc++.h>using namespace std;class Solution {public: // Merges nums2 into nums1 by copying first and sorting afterward. void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) { // No merge is needed when nums2 has no elements. if (n == 0) { return; } // Copy nums2 into the reserved positions of nums1. for (int i = 0; i < n; i++) { nums1[m + i] = nums2[i]; } sort(nums1.begin(), nums1.end()); }};int main() { vector<int> nums1 = {1, 2, 3, 0, 0, 0}; vector<int> nums2 = {2, 5, 6}; int m = 3; int n = 3; Solution solution; solution.merge(nums1, m, nums2, n); for (int value : nums1) { cout << value << " "; } return 0;}Complexity Analysis
Time Complexity: O((M + N) log(M + N)), because the complete array of M + N elements is sorted.
Space Complexity: Depends on the sorting implementation. If internal sorting memory is excluded, it may be described as O(1) auxiliary space, but library sorting can use additional stack or temporary memory.
Better Approach
Since both valid input portions are already sorted, sorting the complete combined array is unnecessary.
A normal merge can compare the smallest unprocessed elements from both arrays and place the smaller one into a temporary array. Temporary storage prevents valid values in nums1 from being overwritten before they are processed.
Algorithm
Initialize
i = 0,j = 0, andindex = 0to traverse the firstmelements ofnums1, thenelements ofnums2, and the temporary result.Create a temporary array
tempof sizem + nso merged elements can be stored without overwriting unprocessed values innums1.While both arrays still contain unprocessed values, compare
nums1[i]andnums2[j]and place the smaller value intotemp[index].Move the pointer belonging to the selected value and increment
indexafter each placement.When one array becomes exhausted, copy all remaining elements from the other array into
temp.Copy the complete
temparray back intonums1.
Dry Run
Merge Two Sorted Arrays Better Appraoch Dry Run.png
Solution
#include <bits/stdc++.h>using namespace std;class Solution {public: // Merges both sorted arrays using temporary storage. void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) { vector<int> temp(m + n); int i = 0; int j = 0; int index = 0; // Compare the smallest unprocessed values from both arrays. while (i < m && j < n) { // Take nums1 value when it is the smaller one. if (nums1[i] <= nums2[j]) { temp[index++] = nums1[i++]; } // Otherwise take the smaller value from nums2. else { temp[index++] = nums2[j++]; } } // Copy any valid nums1 elements that remain. while (i < m) { temp[index++] = nums1[i++]; } // Copy any nums2 elements that remain. while (j < n) { temp[index++] = nums2[j++]; } // Move the merged result back into nums1. for (int k = 0; k < m + n; k++) { nums1[k] = temp[k]; } }};int main() { vector<int> nums1 = {1, 2, 3, 0, 0, 0}; vector<int> nums2 = {2, 5, 6}; int m = 3; int n = 3; Solution solution; solution.merge(nums1, m, nums2, n); for (int value : nums1) { cout << value << " "; } return 0;}Complexity Analysis
Time Complexity: O(M + N), because every element is processed during the merge and copied back at most once.
Space Complexity: O(M + N), because the temporary array stores the complete merged result.
Optimal Approach
Filling nums1 from the beginning could overwrite valid elements that have not been compared yet.
Instead, use the empty positions at the end. Since both arrays are sorted, their largest unprocessed values are at the ends. Compare these values and place the larger one into the last available position of nums1.
Working backward protects all unprocessed elements and removes the need for extra storage.
Algorithm
Initialize
i = m - 1andj = n - 1to point to the largest valid elements ofnums1andnums2. Setk = m + n - 1to the final position ofnums1.While both
iandjremain valid, comparenums1[i]andnums2[j].Place the larger value at
nums1[k], since the last available position must contain the largest remaining element.Move the pointer belonging to the selected value backward and decrement
k.If values remain in
nums2, copy them into the remaining positions ofnums1.Any remaining values from the original
nums1require no movement because they are already in their correct positions.
Dry Run
Merge Two Sorted Arrays Optimal Approach Dry Run.png
Solution
#include <bits/stdc++.h>using namespace std;class Solution {public: // Merges both arrays in place by filling nums1 from the end. void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) { // nums1 already contains the final result when nums2 is empty. if (n == 0) { return; } int i = m - 1; int j = n - 1; int k = m + n - 1; // Place the largest remaining value at the last free position. while (i >= 0 && j >= 0) { // Take nums1 value when it is larger. if (nums1[i] > nums2[j]) { nums1[k--] = nums1[i--]; } // Otherwise place the value from nums2. else { nums1[k--] = nums2[j--]; } } // Only nums2 leftovers need copying into nums1. while (j >= 0) { nums1[k--] = nums2[j--]; } }};int main() { vector<int> nums1 = {1, 2, 3, 0, 0, 0}; vector<int> nums2 = {2, 5, 6}; int m = 3; int n = 3; Solution solution; solution.merge(nums1, m, nums2, n); for (int value : nums1) { cout << value << " "; } return 0;}Complexity Analysis
Time Complexity: O(M + N), where M and N represent the valid element counts in nums1 and nums2. Every value receives at most one comparison and one placement.
Space Complexity: O(1), because only three pointer variables require auxiliary storage.
FAQS
Q1. Why does the Brute Force Approach use a temporary array?
Temporary storage prevents valid values from being overwritten before comparison and allows a standard sorted merge.
Q2. Why does the Better Approach require complete sorting?
Copying nums2 into the reserved positions places all values inside nums1 but does not guarantee sorted order.
Q3. Why does the Optimal Approach merge from the end?
Backward placement uses the reserved positions first and protects unprocessed valid values inside nums1.
Q4. Why do remaining nums1 values require no copying?
Remaining nums1 values already occupy the earliest positions and remain smaller than every value placed later.
Q5. How does the algorithm handle duplicate values?
Every occurrence remains preserved. Equal values receive normal placement without removal.
Q6. What happens when m equals 0 or n equals 0?
When m equals 0, all nums2 values enter nums1. When n equals 0, nums1 already contains the final result.
Be the first to add a comment.