数组中相加和为0的三元组(NC54/考察次数Top30/难度中等)

描述:
给出一个有n个元素的数组S,S中是否有元素a,b,c满足a+b+c=0?找出数组S中所有满足条件的三元组。
注意:
三元组(a、b、c)中的元素必须按非降序排列。(即a≤b≤c)
解集中不能包含重复的三元组。
例如,给定的数组 S = {-10 0 10 20 -10 -40},解集为(-10, -10, 20),(-10, 0, 10)
0 <= S.length <= 1000

示例1
输入:
[-2,0,1,1,2]
返回值:
[[-2,0,2],[-2,1,1]]
(题目来自牛客网)

用C++实现如下

class Solution {
public:
    vector<vector<int>> threeSum(vector<int> &num) {
        //思路,可以先排序处理vector容器内的值,然后以第一个值为基准开始遍历,利用双指针(第一个值后面位置,最后
        //位置)求第二个值和第三个值.(注意三个值都需要防重复)
        sort(num.begin(), num.end());
        vector<vector<int>> res;
        if(num.size() < 3)
            return res;
        for(int i=0; i<num.size()-2; ++i)                                //从第1个开始依次遍历进行求解,从而求出三元组
        {
            int target = -num[i];
            int j = i+1;                                                 //j在左边
            int k = num.size()-1;                                        //k在右边
            //固定第一个,然后利用双指针两头夹逼准则!!!注意三个参数,需要使用参数做三次防重复的功能!!!
            while(j < k)                                                 //相当于一左一右,然后中间凑
            {
                if(num[j] + num[k] > target)
                    --k;
                else if(num[j] + num[k] < target)
                    ++j;
                else                                                     //遇到三元组和为0的情况了
                {
                    vector<int> current = {num[i], num[j], num[k]};
                    res.push_back(current);
                    while(j+1<k && num[j+1] == num[j])                   //防止重复(把第二个后面的相同值过滤掉)
                        ++j;
                    while(k-1>j && num[k-1] == num[k])                   //防止重复(把第三个前面的相同值过滤掉)
                        --k;
                    ++j;                                                 //还可能接着存在
                    --k;                                                 //两边继续跑 
                }
            }
            while(i+1<num.size()-2 && num[i+1]==num[i])                  //i已经用过,如果i+1的值和i一样,则可以跳过
                ++i;                                                     //防止重复(把第一个后面的相同值过滤掉)
        }
        return res;
    }
};

纯手撕代码,如果觉得内容不错麻烦点个赞,后面陆续配上Top100算法题通俗易懂的讲解视频,可以花两个月时间完全掌握,进大厂不是梦,转行狗亲测!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值