双指针算法(四):力扣 88.合并两个有序数组 | 经典例题

题目描述

给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。

初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。你可以假设 nums1 的空间大小等于 m + n,这样它就有足够的空间保存来自 nums2 的元素。

示例
示例一:

输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3

输出:[1,2,2,3,5,6]

示例二:

输入:nums1 = [1], m = 1, nums2 = [], n = 0

输出:[1]

解题思路
看到这个题目,当时的第一反应就是;把第二组直接放在第一组的后面,然后sort排序一次就好了;

这么做也不是不可以,就是在双指针方法面前显得很缓慢,而且很笨拙~

现在来看一下双指针算法的解题思路把

首先,两个数组是升序排列的,我们从最大值开始找(从最小值开始找也行,只不过题目给了现成的 m 和 n)

我们首先使用两个指针就是已经给了的 m 和 n;

然后我们使用额外的一个指针,定义为 pos ,复制用,并且让 pos = m+ n - 1;

pos 的位置,就是结果的最后面的位置;

然后,m 对应的值 和 n 对应的值进行比较;

最大的由pos复制过去,并且对应的指针前移;

如果 m 还没有走完,但是 n 已经走完了,说明 第二个数组已经完全排序进去了,第一个剩下的部分已经是有序的,不用处理;

如果 m 走完了,但是 n 没有走完,说明第二个数组还有剩余的没有加入的元素,由于本身也是有序的,直接遍历加入即可;

需要注意的是,指针的移动使用了 ++ 和 – 的性质,所以和三目运算符配合起来,非常巧妙

代码

class Solution {
     
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
     

        // 方法一:添加后sort排序
        // for(int i=0; i
        //     nums1[m++] = nums2[i];
        // }//把数组2替换掉数组1里的0,然后.sort()排序
        // sort(nums1.begin(),nums1.end());

        // 方法二: 双指针算法
        int pos = m-- + n-- - 1; // pos指针,复制用; -1 因为是下标; 从后往前,先放较大的

        // 留意这个三目表达式;利用了 --  ++ 的技巧,很经典
        while (m >= 0 && n >= 0 ) {
     
            nums1[pos--] = nums1[m] > nums2[n] ? nums1[m--] : nums2[n--];
        }

        while (n >= 0 ) {
     
            nums1[pos--] = nums2[n--] ;
        }
    }
};

结果
双指针算法(四):力扣 88.合并两个有序数组 | 经典例题_第1张图片

你可能感兴趣的:(leetcode详解,#,数据结构与算法,算法,指针,数据结构,leetcode,c++)