01.合并两个有序数组
合并两个有序数组
LeetCode链接
https://leetcode.cn/problems/merge-sorted-array/?envType=study-plan-v2&envId=top-interview-150
解题思路
1.先合并再排序
解题思路
- 将两个数组合并
- 利用STL算法api sort 进行排序
代码流程
//方法1,先合并,再排序
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
//合并
for(int i =0; i < n; i++){
nums1[m+i] = nums2[i];
}
//排序
sort(nums1.begin(), nums1.end());
}
};
复杂度分析
时间复杂度:sort函数类似于快速排序,快排的时间复杂度为 nlog(n),因此时间复杂度为 (m+n)log(m+n)
空间复杂度:快排的空间复杂度为 log(n),因此空间复杂度为 log(m+n)
sort函数详解
//头文件
#include<algorithm>
//函数原型,默认升序
sort(iterator beg, iterator end, _Pred);
// beg 开始迭代器
// end 结束迭代器
// _Pred 比较函数(普通函数,仿函数等)
2.双指针
解题思路
- 定义一个数组 ret 存储排序后的结果,定义两个指针指向 nums1 和 nums2 的头部
- 比较两个指针指向数据的大小,小的存入ret,指针后移
- 结束条件,某一个指针到达最后,将另一个指针后的值存入最后
- 将 ret 赋值给 nums1
代码流程
//方法2,双指针
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int ret[m+n];
int cur;
int p1=0, p2=0;
while(p1 < m || p2 < n){
//边界检测
if(p1 == m){
cur = nums2[p2++];
}else if(p2 == n){
cur = nums1[p1++];
}else if(nums1[p1] <= nums2[p2]){ //大小检测
cur = nums1[p1++];
}else{
cur = nums2[p2++];
}
ret[p1+p2-1] = cur;
}
for(int i = 0; i < m+n; i++){
nums1[i] = ret[i];
}
}
};
复杂度分析
时间复杂度:O(m+n)
空间复杂度:O(m+n)
3.逆向双指针
解题思路
利用前一个数组的长度为 m+n,可以节省空间
- 定义两个指针指向nums1(m-1) p1, nums2(n-1)p2
- 比较两个指针指向的值,大的存入 nums1的末尾
- p1先达到数组头,将nums2接着存入数组nums1; p2先达到数组头,直接结束
代码流程
//逆向双指针
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int p1 = m-1, p2 = n-1;
int cur;
while(p1 >=0 || p2 >= 0){
//边界检测
if(p1 < 0){
cur = nums2[p2--];
}else if(p2 < 0){
break;
}else if(nums1[p1] >= nums2[p2]){ //大小比较
cur = nums1[p1--];
}else{
cur = nums2[p2--];
}
nums1[p1 + p2 + 2] = cur;
}
}
};
复杂度分析
时间复杂度:O(m+n)
空间复杂度:O(1)
总结
本题主要考察双指针的知识,我们需要弄清楚两个点,边界条件 和 大小比较
浙公网安备 33010602011771号