难度:简单
目录
一、问题描述
这里直接采用LeetCode上面的问题描述。
给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。
下面给出示例:
提示:
- nums1.length == m + n
- nums2.length == n
- 0 <= m, n <= 200
- 1 <= m + n <= 200
- -109 <= nums1[i], nums2[j] <= 109
进阶:你可以设计实现一个时间复杂度为 O(m + n) 的算法解决此问题吗?
二、解题思路
1、思路
这里要采用时间复杂度 为 的算法,考虑一下。如果要从前面往后面进行数字的插入的话,那么 nums1 中后面大的数字肯定要往后一个个移动,那么时间复杂度肯定不止是了。
因此这里要考虑从大的着手,并且将大的优先插入到 nums1 的尾部。依次判断 nums1 和nums2 尾部没有被插入到 nums1 最后面的元素的大小,将大的插入到nums1 的最后面,这样顺序依然是从大到小。这里又分两种情况了:
- nums1前面的元素全部插入到nums1 的后面去了
- 此时要用nums2 的数字将nums1前面全部覆盖掉,才能完成两个数组的合并,否则nums2中的数字没有插入到nums1中。当nums2 之中的元素全部插入到,nums1前面时,也完成了两个数组的合并。
- nums2的元素全部插入到了nums1中:
- 此时可以直接跳出循环即可,nums1已经是有序的了,并且nums2的元素也全部插入到了nums1中。
2、极端情况判断
这里需要判断 m 或者 n 初始时,是否是0。
3、极端情况解决
如果 m 或 n之中有一个为0 ,那么就要分情况讨论了:
- 若 m 为 0 ,将nums2 赋给nums1 即可再return即可
- 若 n 为 0,直接return 即可。
三、解题
1、代码实现
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
//这里进行判断是否有其中 一个 数组为空
if(m == 0 || n == 0){
m == 0 ? nums1 = nums2 : nums1 ;
return;
}
//保存nums1 和nums2的最后一个元素的下标
int n1 = m - 1, n2 = n - 1;
//从后往前比较nums1 和 nums2 的大小 ,再从nums1 最后开始保存最大的
for(int i = m + n - 1; i >= 0; i--){
if(nums1[n1] >= nums2[n2]){
nums1[i] = nums1[n1];
n1--;
}else{
nums1[i] = nums2[n2];
n2--;
}
//如果 n2 == -1 说明nums2 的全部元素都插入到nums1 中
if(n2 == -1){
break;
}
//如果n1 == -1, 说明nums1的元素全部插入到了 nums1 的第i个元素后面此时要将 nums2 没插入的元素按照顺序插入到nums1的前面
if(n1 == -1){
for(int j = i - 1; j >= 0; j--){
nums1[j] = nums2[n2--];
}
break;
}
}
}
};
2、时间复杂度 and 空间复杂度
时间复杂度:
空间复杂度: