LeetCode C++ 88.合并两个有序数组

题目

给你两个按非递减顺序排列的整数数组nums1和nums2,另有两个整数m和n,分别表示nums1和nums2中的元素数目。
请你合并mus2到nums1中,使合并后的数组同样按非递减顺序排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组nums1中。为了应对这种情况,nums1的长度为m+n,其中前m个元素表示应合并的元素,后n个元素为0,应忽略。nums2的长度为n。

示例1:

输入: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 中的元素。

示例2:

输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]
解释:需要合并 [1][] 。
合并结果是 [1]

示例3:

输入:nums1 = [0], m = 0, nums2 = [1], n = 1
输出:[1]
解释:需要合并的数组是 [][1] 。
合并结果是 [1] 。
注意,因为 m = 0 ,所以 nums1 中没有元素。nums1 中仅存的 0 仅仅是为了确保合并结果可以顺利存放到 nums1 中。

提示

nums1.length == m + n
nums2.length == n
0 <= m, n <= 200
1 <= m + n <= 200
-109 <= nums1[i], nums2[j] <= 109

思路1-合并后排序

简单粗暴,先把n里的东西逐个遍历加入到nums1里面,然后直接sort完事。

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

思路2-双指针

这个就是循环里面每次取出两个数组中最小的那数进行比较,因为题目说了,本身它就是个升序的,然后每次循环都取出来一个小的存到cur里,又放进数组里,最后sorted数组就是想要输出的,但是题目要求我们不需要在函数里返回,那么就重新赋值给nums1就可以了。

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int p1 =0;
        int 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++];
            }
            // cout << cur << endl;
            sorted[p1+p2-1] = cur;
        }
        for(int i = 0; i != m+n; i++){
            nums1[i] = sorted[i];
        }
    }
};

思路3-逆向指针-(没仔细看)

思路2的办法循环最后把nums1给覆盖了。但是nums1的后半部分是空的,所以我们可以直接覆盖后面的就没事了。因此从后向前遍历,每次取量这之中的较大这放入到nums1的最后面。
因此,nums1数组中又m-p1-1个元素被放入盗了nums1的后半部分,nums2数组中有n-p2-1个元素被放入到nums1的后半部分,而在指针p1的后面,nums1数组有m+n-p1-1个位置。
由于:

m+n-p1-1>=m-p1-1+n-p2-1

等价于:

p2>=-1

永远成立,因此 p1后面的位置永远足够容纳被插入的元素,不会产生p1的元素被覆盖的情况。

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;
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值