一、问题描述:
Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.
Note:
- The number of elements initialized in nums1 and nums2 are m and n respectively.
- You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2.
Example:
Input: nums1 = [1,2,3,0,0,0], m = 3 nums2 = [2,5,6], n = 3 Output: [1,2,2,3,5,6]
给定有序整型数组1和数组2,将数组2合并到数组1中变为一个新的有序数组。
已知数组1和数组2的初始元素数量分别为m和n。
假设数组1有足够的空间来储存来自数组2的额外元素。
二、问题思考:
方法一:暴力方法
将nums2中的元素与nums1的元素逐次比较(从后向前),找到元素当前位置,将其插入数组,再将后面的元素依次向后移动;
特点:基本思路,很容易想到,但操作起来太过麻烦
时间复杂度:最好情况下为O(n)(nums1中的最大元素小于nums2中的最小元素);
最差情况下为O(n+m*n)(nums1中的最小元素大于nums2中的最大元素);
空间复杂度:O(1)。
方法二:排序方法
直接将nums2的元素放入nums1中,再对nums1进行排序;
特点:思路特别简单,而且极易操作
时间复杂度:根据排序算法的选择而不同;
空间复杂度:O(1)。
方法三:逐个比较法
创建一个新数组,比较两个数组中的元素,将较小的元素放入新数组中;
特点:两个数组各遍历1次即可完成,但需要额外空间;
时间复杂度:O(m+n);
空间复杂度:O(m+n)。
方法四:从后向前直接合并
从后向前比较两个数组,将较大的数插入nums1的末位,依次向前;
特点:不容易想到,比较后每个元素放入的位置都是最后的位置,时间和空间上都是最优;
时间复杂度:O(m+n);
空间复杂度:O(1)。
代码实现:
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
int k = m + n - 1;
int i = m - 1;
int j = n - 1;
while(k >= 0){
//注意处理边界问题
if(i < 0 || j < 0)
break;
if(nums1[i] >= nums2[j]){
nums1[k] = nums1[i];
i--;
}
else if(nums1[i] < nums2[j]){
nums1[k] = nums2[j];
j--;
}
k--;
}
/* 注意处理当nums1的元素处理完成而nums2的元素还未就位
nums1 = {3,4,5,0,0,0}
nums2 = {1,2,6}
*/
while(j >= 0){
nums1[i + j + 1] = nums2[j];
j--;
}
}