刷题的一天——排序+双指针

1、给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。

注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

示例:

输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。

这个题一个是可以先合并两个数组然后快速排序,这个是最方便的写法。还可以用双指针的方法。

(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());  //快排
    }
};

虽然快排+合并的代码很好写,但是时间复杂度和空间复杂度上较大。时间复杂度为O((m+n)log(m+n));空间复杂度为(log(m+n))。

(2)双指针

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
    int p1=0,p2=0;
    int nums[m+n];
    int pin = 0;
    while(p1<m||p2<n){      //保证不会超出界限
        if(p1==m){          //nums1遍历完了就继续加入nums2的元素
           pin = nums2[p2++];
        }else if (p2==n){    //nums2遍历完了就继续加入nums1的元素
            pin = nums2[p1++];
        }else if (nums1[p1]<nums2[p2]){     //下一个条件同理,加入小数
            pin = nums1[p1++];
        }else{
            pin = nums2[p2++];
        }
         nums [p1+p2-1]=pin;                 //把pin里面取到的数加入nums数组
    }
    for(int a = 0;a<p1+p2;a++){
        nums1[a]=nums[a];                      //因为题目要求元素在nums1里面,所以要把nums里的元素替换进去。
    }

    }
};

(3)逆双指针

           在(2)中,同样使用的双指针法,但不同的是(3)是从末尾开始遍历,即最大值开始填充进入nums1数组,这样可以避免nums1正向遍历元素被覆盖的问题。

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
    int p1 = m-1;                          //双指针,从末尾开始遍历
    int p2 = n-1;
    int j = nums1.size()-1;
    while(p1 >= 0 || p2 >=0){           //防止溢出
        if(p1==-1){
            nums1[j--] = nums2[p2--];    
        }else if (p2==-1) { 
            nums1[j--] = nums1[p1--];
        }else if(nums1[p1]<nums2[p2]){
            nums1[j--] = nums2[p2--];
        }else {
            nums1[j--] = nums1[p1--];
        }
    }         
       
    }
};

害,我果然还是太菜了,要多练练啊。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值