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

Posted 码农指南

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数组中相加和为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算法题通俗易懂的讲解视频,可以花两个月时间完全掌握,进大厂不是梦,转行狗亲测!

以上是关于数组中相加和为0的三元组(NC54/考察次数Top30/难度中等)的主要内容,如果未能解决你的问题,请参考以下文章

链表相加(NC40/考察次数Top24/难度中等)

二叉树中是否存在节点和为指定值的路径(NC9/考察次数Top63/难度简单)

二叉树中是否存在节点和为指定值的路径(NC9/考察次数Top63/难度简单)

在旋转过的有序数组中寻找目标值(NC48/考察次数Top34/难度简单)

《程序员代码面试指南》第八章 数组和矩阵问题 不重复打印排序数组中相加和为给定值的所有二元组和三元组

数组中出现次数超过一半的数字(NC73/考察次数Top46/难度简单)