法一:需要额外空间的归并排序。
法二:不需要额外空间的反向归并排序。
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
//因为最后合并的数组只要nums1的前m个元素
//所以我们把前m个元素存一下,然后归并排序放入nums1中
// vector<int> nums3(m);
// for(int i = 0; i < m; ++i){
// nums3[i] = nums1[i];
// }
// int left = 0, right = 0;
// int i = 0;
// while(left < m && right < n){
// if(nums3[left] <= nums2[right]){
// nums1[i++] = nums3[left++];
// }
// else{
// nums1[i++] = nums2[right++];
// }
// }
// if(left == m){
// while(right < n){
// nums1[i++] = nums2[right++];
// }
// }
// else{
// while(left < m){
// nums1[i++] = nums3[left++];
// }
// }
//nums1后面有额外空间,把大的数字插在后面就不会影响到前面了
int left = m-1,right = n-1;
int i = m+n-1;
//从后往前数,left到哪里不好判断,判断right,right<0就是越界了,可以退出了
while(left >= 0 && right >= 0){
if(nums1[left] > nums2[right]){
nums1[i--] = nums1[left--];
}
else{
nums1[i--] = nums2[right--];
}
}
if(left < 0){
while(right >= 0){
nums1[i--] = nums2[right--];
}
}
else if(right < 0){
while(left >= 0){
nums1[i--] = nums1[left--];
}
}
}
};
双指针模拟归并排序,反着放就行了
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
//归并排序的merge部分,但是得开一个大数组然后复制到1中
//其实并不用,只要进行尾排序就行了,从后往前放,这样绝对不会影响到nums1数字
int l = m-1, r = n-1;
int k = m+n-1;
while(l>=0&&r>=0){
//保证归并排序的有序性,相当的nums1要放在前面
if(nums1[l] > nums2[r]){
nums1[k--] = nums1[l--];
}
else{
nums1[k--] = nums2[r--];
}
}
if(l<0){
while(r>=0){
nums1[k--] = nums2[r--];
}
}
}
};
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
//不是简单的归并,简单的归并还得会破坏nums1,开一个辅助数组又浪费空间,所以我们从后往前尾排序
int k = m + n -1;
m-=1;
n-=1;
while(m >= 0 && n >= 0){
if(nums1[m] > nums2[n]){
nums1[k--] = nums1[m--];
}
else{
nums1[k--] = nums2[n--];
}
}
//如果数组2用完了,数组1剩下的本身就有序
if(m < 0){
while(n >= 0){
nums1[k--] = nums2[n--];
}
}
}
};