You are given two integer arrays nums1
and nums2
, sorted in non-decreasing order, and two integers m
and n
, representing the number of elements in nums1
and nums2
respectively.
Merge nums1
and nums2
into a single array sorted in non-decreasing order.
The final sorted array should not be returned by the function, but instead be stored inside the array nums1
. To accommodate this, nums1
has a length of m + n
, where the first m
elements denote the elements that should be merged, and the last n
elements are set to 0
and should be ignored. nums2
has a length of n
.
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 + n
nums2.length == n
0 <= m, n <= 200
1 <= m + n <= 200
-109 <= nums1[i], nums2[j] <= 109
Follow up: Can you come up with an algorithm that runs in O(m + n)
time?
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force strategy for merging two sorted lists is like combining two decks of playing cards that are already in order. We can simply combine the two decks and then re-sort the entire merged deck to get the final sorted result.
Here's how the algorithm would work step-by-step:
def merge_sorted_array_brute_force(first_array, first_array_length, second_array, second_array_length):
# Create a new array to hold all elements
merged_array = [0] * (first_array_length + second_array_length)
# Copy elements from the first array
for first_array_index in range(first_array_length):
merged_array[first_array_index] = first_array[first_array_index]
# Copy elements from the second array to the end of the merged array
for second_array_index in range(second_array_length):
merged_array[first_array_length + second_array_index] = second_array[second_array_index]
# Sort the merged array.
# This combines and sorts the data.
merged_array.sort()
# Copy the sorted array back into the first array.
# Required by the problem statement.
for merged_array_index in range(first_array_length + second_array_length):
first_array[merged_array_index] = merged_array[merged_array_index]
The most efficient way to combine two sorted sequences into one sorted sequence is to work backward. By starting from the end, we avoid the need to constantly shift elements around, which would be slow. This method fills the combined sequence from the end to the beginning, ensuring everything stays in order.
Here's how the algorithm would work step-by-step:
def merge_sorted_array(nums1, nums1_length, nums2, nums2_length):
merged_array_length = nums1_length + nums2_length
# Initialize pointers to the end of each array.
first_array_pointer = nums1_length - 1
second_array_pointer = nums2_length - 1
merged_array_pointer = merged_array_length - 1
# Merge from the end until one array is exhausted.
while first_array_pointer >= 0 and second_array_pointer >= 0:
# Pick the larger element and place it at the end.
if nums1[first_array_pointer] > nums2[second_array_pointer]:
nums1[merged_array_pointer] = nums1[first_array_pointer]
first_array_pointer -= 1
else:
nums1[merged_array_pointer] = nums2[second_array_pointer]
second_array_pointer -= 1
merged_array_pointer -= 1
# Copy any remaining elements from nums2 to nums1.
# These are already in sorted order.
while second_array_pointer >= 0:
nums1[merged_array_pointer] = nums2[second_array_pointer]
second_array_pointer -= 1
merged_array_pointer -= 1
Case | How to Handle |
---|---|
nums1 is empty (m=0), nums2 has elements (n>0) | Simply copy all elements from nums2 to nums1. |
nums2 is empty (n=0), nums1 has elements (m>0) | nums1 is already sorted, no action required. |
Both arrays are empty (m=0, n=0) | No operation needed; nums1 remains empty. |
All elements in nums2 are smaller than all elements in nums1 | The solution should correctly place all elements of nums2 at the beginning of nums1. |
All elements in nums2 are larger than all elements in nums1 | The solution should correctly place all elements of nums2 at the end of nums1. |
nums1 and nums2 contain duplicate values | The merging process should handle duplicates correctly, maintaining the sorted order. |
nums1 contains very large or very small numbers | The comparison logic should work correctly even with extreme integer values (avoiding overflow during comparison if possible, relying on language's int comparison behavior). |
m + n equals the maximum array size representable by the programming language | Ensure no out-of-bounds write occurs when merging elements near the array boundary (check index bounds before accessing). |