Leetcode : 两数,三数,四数之和问题剖析

博主有话要吐槽

在这里插入图片描述

话不多说,开始剖析问题

你一定遇到以下问题,对其头脑发热:

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

题目的目的: 给定一个序列(未排序),多数相加等于特定值,找出其所有符合条件的所有 多数 序列。



讲论解法

1. 我们讲解以下 双数 的解法: 左右指针法(双指针)

在这里插入图片描述

2. 左指针 L + 右指针 R 索引的序列元素值等于给定值,则记录其序列,并++L, – R 操作,缩短区间准备下一次查找 相加的值等于 目标值的 L,R 指向元素

在这里插入图片描述

3. 左指针 L + 右指针 R 索引的序列元素值小于给定值,说明当前 L 索引到的值小了,需要向右继续移动,指向次大的值,继续判定

在这里插入图片描述

4. 左指针 L + 右指针 R 索引的序列元素值大于给定值,说明当前 R 索引到的值大了,需要向左继续移动,指向次小的值,继续判定

在这里插入图片描述

5. 其可查询条件为 L < R

注意: 由于是查找不重复的二数之和,因此当我们遇到已经使用过的左右值(该值符不符合都无所谓),都要在进行移动时对其进行判重,重复的话过滤掉。

这里有些爱问题的的小朋友就想问了,万一 重复的元素相加就是等于给定值呢,我们过滤掉不就失去了其结果了吗,事实上我们是在使用过该重复元素的一个元素已经判定其不合格了,假若它们真的相加等于给定值,那 L + R 一定会指向到这两个元素的。

我们用简单的例子分析一下我们的思路处理上述的情况:

在这里插入图片描述

2. 我们讲解 三数之和 的解法: 占位左右指针法(双指针)

这个解法的思路是这样的

将三个数的一个数固定,利用双指针在剩余区间内的元素中去找符合条件的剩余两个数。

  • 当first_num 固定在第一位时且符合条件的 L-R 区间内的剩余两数找全后,移动 first_num 固定在下一个位置上,这样就能完成所有符合的查找。

注意: 且 first_num 移动时,注意判重操作,避免重复三数项。

在这里插入图片描述

class Solution {
public:

vector<vector<int>> threeSum(vector<int>& nums) {
    if(nums.size()<=2) 
       return {};
    sort(nums.begin(),nums.end());
    for(decltype(nums.size()) i=0;i!=nums.size()-2;++i){
        int l=i+1,r=nums.size()-1;
        while(l<r){
            if(nums.at(i)+nums.at(l)+nums.at(r) == 0) {
                ivecSet.push_back({nums.at(i),nums.at(l),nums.at(r)});
                int v1=nums.at(l),v2=nums.at(r);
                while(nums.at(++l)==v1 && l<r);
                while(nums.at(--r)==v2 && r>l);

            }
            else if(nums.at(i)+nums.at(l)+nums.at(r) > 0)  --r;
            else if(nums.at(i)+nums.at(l)+nums.at(r) < 0)  ++l;


        }
        while(i+1 !=nums.size()-2 && nums.at(i) == nums.at(i+1))
            ++i;
    }
    return ivecSet;
}
private:
    vector<vector<int>> ivecSet;
};

3. 我们讲解 四数之和 的解法: 占两位左右指针法(双指针)

哈哈,占两个位置,利用双指针对剩余 区间进行查找即可

猜你喜欢

转载自blog.csdn.net/chongzi_daima/article/details/107456214
今日推荐