3Sum算法

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移位后,就要判断其是否和上一位是否相等,如果相等,继续移位,直到不相等为止。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值