
Problem Statement
In this task, we are provided with two sorted integer arrays, nums1 and nums2. We are also given two integers, m and n, indicating the number of active elements in nums1 and nums2, respectively. The goal is to merge nums1 and nums2 into a single sorted array in non-decreasing order. The merged result should not be returned but stored within nums1. To facilitate the merging, the array nums1 is structured to have a length of m + n, where the first m entries are the initial elements, and the remaining n slots are initially zeroed out to accommodate the elements of nums2. It is crucial to ensure the elements from both arrays are merged directly into nums1 without using additional arrays for output.
Examples
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 arrays we are merging are [1,2,3] and [2,5,6]. The result of the merge is [1,2,2,3,5,6] with the underlined elements coming from nums1.
Example 2
Input:
nums1 = [1], m = 1, nums2 = [], n = 0
Output:
[1]
Explanation:
The arrays we are merging are [1] and []. The result of the merge is [1].
Example 3
Input:
nums1 = [0], m = 0, nums2 = [1], n = 1
Output:
[1]
Explanation:
The arrays we are merging are [] and [1]. The result of the merge is [1]. Note that because m = 0, there are no elements in nums1. The 0 is only there to ensure the merge result can fit in nums1.
Constraints
nums1.length == m + nnums2.length == n0 <= m, n <= 2001 <= m + n <= 200-109 <= nums1[i], nums2[j] <= 109
Approach and Intuition
Before diving into the solution, understanding the constraints and the default setup of nums1 and nums2 is essential. Here's a structured approach to achieve the merging:
- Utilize two pointers starting from the end of the active elements of both arrays (
m-1fornums1andn-1fornums2). Additionally, use a third pointer to place elements from the end to the beginning ofnums1, starting at the positionm+n-1. - Compare the elements at these pointers:
- If the element in
nums2is greater than or equal to the element innums1, place thenums2element at the current index innums1determined by the third pointer, and move the pointer innums2backwards. - Otherwise, move the element in
nums1to the current index, and move the pointer innums1backward.
- If the element in
- If elements remain in
nums2afternums1is exhausted, copy them directly to the beginning ofnums1.
These steps ensure that we manipulate nums1 in-place, adhering to the memory constraints and the requirement to not return the merged array but store it within nums1. The decision to merge from the back of nums1 allows us to efficiently utilize its space without overwriting any elements before they are merged. This method leverages the sorted property of the arrays, ensuring that at each step, the largest of the remaining elements is correctly placed at the end of nums1, filling up from back to front.
Solutions
- C++
- Java
- JavaScript
- Python
class Solution {
public:
void mergeSortedArrays(vector<int>& first, int size1, vector<int>& second, int size2) {
int index1 = size1 - 1;
int index2 = size2 - 1;
for (int indexMerged = size1 + size2 - 1; indexMerged >= 0; indexMerged--) {
if (index2 < 0) {
break;
}
if (index1 >= 0 && first[index1] > second[index2]) {
first[indexMerged] = first[index1--];
} else {
first[indexMerged] = second[index2--];
}
}
}
};
The provided C++ code defines a method mergeSortedArrays that merges two presorted integer vectors into one of the vectors, specifically into the first vector. The function takes two vectors, first and second, and their respective sizes, size1 and size2.
- The code initializes two pointers,
index1andindex2, at the end of the non-empty parts of bothfirstandsecondvectors respectively. - A third pointer,
indexMerged, is also initialized at the last position of the combined array size. - It uses a
forloop to iterate backwards through thefirstvector's extended size (which includes room for thesecondvector's elements). - Inside the loop, the elements from
firstandsecondare compared. The larger element is placed into the current position ofindexMergedin thefirstvector. - The loop terminates early if all elements from the
secondvector have been placed into thefirst.
This method ensures that the merged array is sorted without needing additional storage space, effectively integrating the two arrays into a single sorted array in a space-efficient manner. This solution is particularly efficient for scenarios where extra space utilization needs to be minimized.
class Solution {
public void mergeSortedArrays(int[] array1, int len1, int[] array2, int len2) {
int index1 = len1 - 1;
int index2 = len2 - 1;
for (int i = len1 + len2 - 1; i >= 0; i--) {
if (index2 < 0) {
break;
}
if (index1 >= 0 && array1[index1] > array2[index2]) {
array1[i] = array1[index1--];
} else {
array1[i] = array2[index2--];
}
}
}
}
The provided Java solution tackles the problem of merging two sorted arrays into one sorted array. The approach modifies the first array (array1) to include all elements from both arrays, as it assumes that array1 has enough space to hold elements from both array1 and array2.
Here's how the merging process is executed:
- Initialize two pointers,
index1andindex2, to point to the ends ofarray1andarray2respectively. - Use a loop that goes backwards through
array1, starting from its last position, which is the sum oflen1andlen2minus one, and decrements down to zero. - In each iteration of the loop:
- If
index2is less than zero, end the loop, as it means all elements fromarray2have been placed. - Compare the current elements pointed by
index1andindex2ofarray1andarray2respectively. - Place the larger element at the current position
iinarray1and decrement the respective index (index1orindex2).
- If
This approach ensures that the larger elements are placed at the end of array1 first, making efficient use of space while preserving the sorted order. This solution is efficient and executes in linear time relative to the total number of elements, or O(n + m), where n is the number of elements in array1 and m is the number of elements in array2.
var mergeArrays = function (array1, len1, array2, len2) {
let index1 = len1 - 1;
let index2 = len2 - 1;
for (let position = len1 + len2 - 1; position >= 0; position--) {
if (index2 < 0) {
break;
}
if (index1 >= 0 && array1[index1] > array2[index2]) {
array1[position] = array1[index1--];
} else {
array1[position] = array2[index2--];
}
}
};
Merge two sorted arrays in-place in a predefined space within the first array. The function mergeArrays efficiently tackles this with the following steps:
- Initialize two pointers
index1andindex2to point to the end of the actual elements inarray1andarray2, respectively. - Begin a reverse iteration from the total length of both arrays combined.
- Compare elements from the end of both arrays:
- If the current element in
array1is larger, place it in the current position and decrement theindex1. - Otherwise, place the element from
array2and decrementindex2.
- If the current element in
- Exit earlier if
array2is exhaustively merged, indicated byindex2being less than zero.
This function ensures optimal integration of two arrays by filling the first array from the end, thereby avoiding the overhead of moving unmerged elements with each insertion.
class Solution:
def combine(self, first_list: List[int], len1: int, second_list: List[int], len2: int) -> None:
# Initialize pointers for the merge process
first_ptr = len1 - 1
second_ptr = len2 - 1
# Start from the end of the first list and fill backwards
for idx in range(len1 + len2 - 1, -1, -1):
if second_ptr < 0:
break
if first_ptr >= 0 and first_list[first_ptr] > second_list[second_ptr]:
first_list[idx] = first_list[first_ptr]
first_ptr -= 1
else:
first_list[idx] = second_list[second_ptr]
second_ptr -= 1
The provided Python code defines a method to merge two pre-sorted integer arrays. This method, named combine, modifies the first array first_list in place by integrating elements from second_list, resulting in a single, fully merged and sorted array.
Memory Efficiency: The merging happens in-place on the
first_listutilizing the extra space at its end, which ensures that no additional storage is needed.Merging Logic: The solution uses three pointers:
first_ptrstarts at the end of the actual elements infirst_list(ignoring the extra space).second_ptrstarts at the end ofsecond_list.idxis used for setting the next value infirst_liststarting from the end towards the beginning.
Process Details:
- The function fills
first_listby comparing values from the end of bothfirst_listandsecond_list, copying the larger value into the current position pointed byidx. - Decrement the pointers (
first_ptrorsecond_ptr) accordingly. - The loop stops when all elements of
second_listhave been merged, assuming there's enough space infirst_list.
- The function fills
Ensure to have the appropriate length setup (i.e., both len1 and the reserve space for second_list included in first_list) before calling this function to avoid errors. The function is particularly optimal when you need to integrate two lists without additional memory overhead, typical in scenarios like merging logs, event streams, or sorted data from different sources directly into a designated buffer space.