注:个人学习用,代码与时间复杂度内容来自于力扣官方题解,侵删
直接合并后排序
- 时间复杂度:O((m+n)log(m+n))。 排序序列长度为 m+n,套用快速排序的时间复杂度即可,平均情况为 O((m+n)log(m+n))。
- 空间复杂度:O(log(m+n))。 排序序列长度为 m+n,套用快速排序的空间复杂度即可,平均情况为 O(log(m+n))。
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());
}
};
双指针
分别为两个数组设置p1、p2作为头部指针
- 时间复杂度:O(m+n)O(m+n)O(m+n)。 指针移动单调递增,最多移动 m+nm+nm+n 次,因此时间复杂度为 O(m+n)O(m+n)O(m+n)。
- 空间复杂度:O(m+n)O(m+n)O(m+n)。 需要建立长度为 m+nm+nm+n 的中间数组 sorted\textit{sorted}sorted。
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int p1=0,p2=0;
int sorted[m+n];
int cur;
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++];
}
sorted[p1+p2-1]=cur;
}
for(int i=0;i!=m+n;i++){
nums1[i]=sorted[i];
}
}
};
逆向双指针
从后面放入
- nums1放入的元素个数:m-1-p1
- nums2放入的元素个数:n-1-p2
- 指针p1后面的位置:m+n-1-p1
时间复杂度
- 时间复杂度:O(m+n)。 指针移动单调递减,最多移动 m+n次,因此时间复杂度为 O(m+n)。
- 空间复杂度:O(1)。 直接对数组 nums1原地修改,不需额外增加空间。
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int p1=m-1,p2=n-1;
int tail=m+n-1;
int cur;
while(p1>=0||p2>=0){
if(p1==-1){
cur=nums2[p2--];
}
else if(p2==-1){
cur=nums1[p1--];
}
else if(nums1[p1]>nums2[p2]){
cur=nums1[p1--];
}
else{
cur=nums2[p2--];
}
nums1[tail--]=cur;
}
}
};