3Sum算法

来源:互联网 发布:苹果cms使用cdn问题 编辑:程序博客网 时间:2024/06/06 07:02

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

Note: 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]]


这道题和之前做的4sum有点类似,就是在一个数组中,找出3个不同的数,使得相加等于0,最后输出所有符合题意的3个数。

class Solution {public:    vector<vector<int>> threeSum(vector<int>& nums) {        if(nums.size() <=2) return {};        vector<vector<int> > ans;        sort(nums.begin(), nums.end());        for(int i =0; i < nums.size();){            int start = i+1, end = nums.size()-1;            while(start < end){                if(nums[i]+nums[start]+nums[end] == 0){                    ans.push_back({nums[i],nums[start],nums[end]});                    start++;                    end--;                    while((start < end) && nums[start] == nums[start-1]) start++;                    while((start < end) && nums[end] == nums[end+1]) end--;                }else if(nums[i]+nums[start]+nums[end]<0){                    start++;                    while((start < end) && nums[start] == nums[start-1]) start++;                }else{                    end--;                    while((start < end) && nums[end] == nums[end+1]) end--;                }            }            i++;            while((i < nums.size()) && nums[i] == nums[i-1])                i++;        }        return ans;    }};


这道题一开始我参考了一下之前4sum的做法,就是用3层循环,然后在其中加入一些优化,但是并没有ac,在最后几个测试样例中超时了。这里是之前4sum的做法。点击打开链接

当然,排序还是得要有的。
既然这样不行的话,就要换另一种思路了,得把复杂度降下来,既然3层循环加优化都不行,那么就只有2层循环了。我的思路是这样的,先定下第一个数,第二个数为第一个数的下一位,第三个数为序列的最后一位。第一个数不动,第二个数和第三个数分别往中间靠拢,直到第二个数的序列号大于等于第三个数时为止。简易的图如下:

1 2→→→      ←←←3

接下来就是什么时候第二、三个数要往中间靠拢了。当a1 + a2 + a3 = 0时,(这里的a1、a2、a3表示第1-3个数),这表示已经找到符合题意的3个数了,需要寻找下一组数,这时a2和a3都要往中间靠拢一步。当a1 + a2 + a3 > 0时,说明a3太大了,需要更小一些的,所以此时a3往中间靠拢一步。a1 + a2 + a3 < 0时,说明a2太小了,需要更大一些的,所以此时a2往中间靠拢一步。

这样大致就差不多了,还需要注意一点就是不能出现重复的结果。每当a1a2a3移位后,就要判断其是否和上一位是否相等,如果相等,继续移位,直到不相等为止。