原题:合并两个有序数组
1、自解(偷懒)
class SolutionMy {
public:
void merge(vector& nums1, int m, vector& nums2, int n) {
for (int i = 0; i < nums2.size(); ++i) {
nums1[m+i] = nums2[i];
}
sort(nums1.begin(),nums1.end());
}
};//偷懒方法,利用了algorithm库
2、自写双指针(代码简洁度很垃)
class SolutionTwoptr {
public:
void merge(vector& nums1, int m, vector& nums2, int n) {
//变量创建
int leftptr;
int rightptr;
int count;
vectormyvec;
//变量初始化
leftptr = 0;
rightptr = 0;
count = 0;
if (m != 0 && n != 0){
if (nums1[0] >= nums2[0]){
myvec.push_back(nums2[0]);
rightptr++;
}else{
myvec.push_back(nums1[0]);
leftptr++;
}
}else if(m == 0){
myvec.push_back(nums2[0]);
rightptr++;
}else if(n == 0){
myvec.push_back(nums1[0]);
leftptr++;
}
//遍历
while (leftptr != m || rightptr != n){
if (leftptr == m){
myvec.push_back(nums2[rightptr++]);
}//左满
else if (rightptr == n){
myvec.push_back(nums1[leftptr++]);
}//右满
else if (leftptr != m && rightptr != n){
if (nums1[leftptr] >= nums2[rightptr]){
myvec.push_back(nums2[rightptr++]);
} else{
myvec.push_back(nums1[leftptr++]);
}
}//daily遍历
}//while
for (int i = 0; i < m+n; ++i) {
nums1[i] = myvec[i];
}
}//merge
};//正经方法,也是常规方法,经典双指针
3、自写反向双指针(空间复杂度低)
class SolutionTwoptrVerse {
public:
void merge(vector& nums1, int m, vector& nums2, int n) {
//声明
int ptrL,ptrR;
//初始化
ptrL = m;
ptrR = n;
//方法
while (ptrL != 0 || ptrR != 0){
if (ptrL > 0 && ptrR > 0){
if (nums1[ptrL - 1] >= nums2[ptrR - 1]){
nums1[ptrR + ptrL - 1] = nums1[ptrL - 1];
ptrL--;
}else{
nums1[ptrR + ptrL - 1] = nums2[ptrR - 1];
ptrR--;
}
}
else if (ptrL == 0 && ptrR > 0){
nums1[ptrR - 1] = nums2[ptrR - 1];
ptrR--;
}
else if (ptrR == 0 && ptrL > 0){
break;
}
}//while循环界
}//merge
};//自写反向双指针
总结:
- 调用algorithm,将nums1和nums2无序堆积在一起之后快排,写出来没啥技术含量,不过效率蛮高的。双指针正向,要是想从正向不消耗额外空间,时间复杂度会大大增加,因此没必要通过很多的时间交换空间,这里开辟额外向量存放有序数组最后重初始化nums1。双指针反向,由于反向和向量特性,nums1前面存放有意义的部分,长度为m,后面n个空间没有用。这里可以利用从后向前遍历的方法,双指针每走一下都要向nums1后面的空间填充。考虑最简单的方法,nums2中的数字全部大于nums1中最大的数字,这时直接就是结果。不是这个特殊情况时也类似。总之nums1大小正好够装m+n 。
三个方法最快的是调用快排,毕竟是最快的排序。第二快的是反向双指针,因为没有额外空间损耗且一次遍历。比较慢的是正向双指针,需要额外空间承接新的有序向量。简单题中的有趣题。



