3Sum

Given an array nums of n integers, are there elements a, b, c in nums 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.

Example:

Given array nums = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]

这道题让我们在数组内找三个和为0的数,要求找到的三个数不能重复。
我一开始看到就想到2sum的问题,fix一个数target,然后找另外两个数使得他两之和为-target。我的写法是用一个set记录数组的元素,然后双循环数组求两数之和,当和为-target,加入结果集,当然加之前先做个判断,是否在结果集已经有了。复杂度差不多是0(N^2),结果还是超时了。

翻阅大佬的博客,看完后赏心悦目,优秀的解法用到了双指针操作。首先对数组排序,然后再找数字可以起到有效剪枝的效果。遍历数组,每次fix住一个数target,当target为正数,那直接退出,因为排完序后的数组后面的数肯定比target大,那不可能存在两数之和为负了。在具体找另外两个数之前还要对fix的数做个去重,如果target和相邻的数相等,那么直接将fix数的指针右移。然后就是找另外两数了,找另外两个数的时候也需要做类似的操作来去重,话不多说,还是代码说的更清楚。

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> res;
        
        int i,j;
        sort(nums.begin(),nums.end());
        if(nums.size()<3||nums.front()>0||nums.back()<0) return res;
        for (int k=0;k<nums.size();k++)
        {
            //去掉重复fix住的数
            while (k > 0 && k<nums.size() && nums[k]==nums[k-1]) k++;
            if (k < 0 || k >= nums.size()) break;
            int target = -nums[k];
            // 若target为负,说明nums[i]为正,那么说明i之后的都为正数,不可能为负数
            if (target<0) break;
            i=k+1;
            j=nums.size()-1;
            while(i<j)
            {
                if(nums[i]+nums[j]==target)
                {
                    res.push_back({nums[k],nums[i],nums[j]});
                    // 去重
                    while(i<j&&nums[i]==nums[i+1]) i++;
                    while(i<j&&nums[j]==nums[j-1]) j--;
                    i++;
                    j--;
                }
                else if (nums[i] + nums[j] < target) i++;
			    else j--;
            }
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值