目录
- 1、题目
- 2、思路1
- 3、代码1
- 4、思路2
- 5、代码2
1、题目
给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1中,使 nums1 成为一个有序数组。
初始化 nums1 和 nums2的元素数量分别为 m 和n。你可以假设 nums1 的空间大小等于 m + n,这样它就有足够的空间保存来自 nums2的元素。
示例 1:
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]示例 2:
输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]提示:
-
nums1.length == m + n -
nums2.length == n -
0 <= m, n <= 200 -
1 <= m + n <= 200 -
-109 <= nums1[i], nums2[i] <= 109
2、思路1
(二路归并)
- 1、新开一个数组
ans用来存贮合并后的有序元素 - 2、定义两个指针
i,和j分别指向nums1和nums2,每次将两个指针所指向的较小的数添加到ans中 - 3、将
ans数组赋值给num1
时间复杂度:
空间复杂度为: 由于新开了一个数组ans,因此空间复杂度为。
3、代码1
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
vector<int> ans(n+m);
int i = 0, j = 0 , t = 0;
while( i < m && j < n)
{
if(nums1[i] <= nums2[j]) ans[t++] = nums1[i++];
else ans[t++] = nums2[j++];
}
while( i < m) ans[t++] = nums1[i++];
while( j < n) ans[t++] = nums2[j++];
nums1 = ans;
}
};4、思路2
在上面二路归并算法中,需要临时一个构建一个数组,空间复杂度不是常数,通过观察题,没有充分利用题目所给的条件,nums1已经开够了足够大,如果直接在nums1上合并,便不需要额外的空间,而如果从前往后合并,则会覆盖元素得到错误结果,再通过观察,如果从后往前合并的方式,则不会覆盖,是理想的解法,时间,空间常数。
步骤如下
- 1、初始化
k = m + n - 1 - 2、定义两个指针
i,和j分别指向nums1和nums2,每次将两个指针所指向的较大的数放在k的位置,同时i或者j 和k同时减1 - 3、如果
while(j >= 0)再将nums2中剩余的数放入nums1中
5、代码2
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int k = m + n - 1;
int i = m - 1,j = n - 1;
while(i >= 0 && j >= 0)
{
if(nums1[i] >= nums2[j]) nums1[k --] = nums1[i --];
else nums1[k --] = nums2[j --];
}
while(j >= 0) nums1[k --] = nums2[j --];
}
};原题链接:88. 合并两个有序数组
题目
