3Sum 三数之和

题目描述

Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note:

  • Elements in a triplet (a,b,c) must be in non-descending order. (ie, abc)
  • The solution set must not contain duplicate triplets.

    For example, given array S = {-1 0 1 2 -1 -4},

    A solution set is:
    (-1, 0, 1)
    (-1, -1, 2)

解析:

这道题让我们求三数之和,比之前那道Two Sum 两数之和要复杂一些,我们还是要首先对原数组进行排序,然后开始遍历排序后的数组,这里注意不是遍历到最后一个停止,而是到倒数第三个就可以了,然后我们还要加上重复就跳过的处理,对于遍历到的数,我们用0减去这个数得到一个target,我们只需要在之后找到两个数之和等于target即可,这样一来问题又转化为了求two sum,这时候我们一次扫描,找到了等于sum的两数后,加上当前遍历到的数字,按顺序存入结果中即可,然后还要注意跳过重复数字。

实现代码:

             class Solution {
public:
    vector<vector<int> > threeSum(vector<int> &num) {
        vector<vector<int>> res;
        sort(num.begin(), num.end()); //首先排序
        for (int k = 0; k < num.size(); ++k)
        {
            if (num[k] > 0) break; //因为是排好序了,如果num[k]>0,之后一定找不到三个数相加为0;
            if (k > 0 && num[k] == num[k - 1]) continue; //跳过相等的两个数;不需要重复寻找;
            int target = 0 - num[k]; //转换为两数求和得到target;
            int i = k + 1, j = num.size() - 1; //从k位置一直寻找到结束;
            while (i < j)
            {
                if (num[i] + num[j] == target)
                {
                    res.push_back({num[k], num[i], num[j]});
                    while (i < j && num[i] == num[i + 1]) ++i;//跳过相同的数
                    while (i < j && num[j] == num[j - 1]) --j;//...
                    ++i; --j; //从两边向中间收缩;
                } 
                else if (num[i] + num[j] < target) ++i; //相加的数小了,向右靠;
                else --j; //相加的数大了,向左靠;
            }
        }
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_40039738/article/details/80056017