LeetCode【#15】3Sum

题目链接:

点击跳转

 

题目:

Given an array nums of n integers, are there elements abc 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,要求找出的解不能出现重复的。

 

解题思路:

先进行排序

然后固定一个数,即遍历从0到 len -2(确保后面还有两个数)。这样子用两个下标  s 和 e 指向(从固定那个数之后)第一个数和最后一个数,然后三者求和(这里固定的那个数 >0 的时候,这时后面的数肯定比这个固定的数大,那么三者之和肯定不为0,所以这种情况下,就可以提前结束了)。三种情况:

第一种情况  <0 :说明数太小了,那么 s++

第二种情况  >0 :说明数太大了,那么 e--

第三种情况  =0 :说明是我们要的答案,保存下来,然后同时 s++ 和 e--。

例子:

[-1, 0, 1, 2, -1, -4] 排序后得到:[-4, -1, -1, 0, 1, 2] 
然后固定一个数,比如现在是 
固定了 -4,没有可能 
固定了 -1,此时后面指向 -1和2,求和为0,所以保存;然后到0 和 1 ,满足,保存下来 
固定了 -1,此时后面指向 0和 2,数太大了,所以指向 0和 1 满足,保存下来

根据上面那个例子,是可以找到所有结果的,但是出现问题,那就是有可能会有重复的情况

重复情况出现的原因

1、比如固定的数本来是 -1 了,此时后面有满足的;下一次固定的数还是 -1,所以会产生重复的情况

2、固定的数不变,然后后面 出现满足的数之后,进行同时 s++ 和 e--,对应的两个数还是和之前两个数一样,那就产生重复的情况

所以

第一种的解决方案,在遍历从0到 len -2 时,我们当处理这个固定的数时,下一次找到的数,一定是要不同的;

第二种的解决方案,我们用一个变量记录两个数的前一个数,当出现满足条件,而且和记录过的那个数不同,才保存下来。

 

AC代码:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        
        vector<vector<int>> res;
        vector<int> temp;
        
        sort(nums.begin(),nums.end());
        int len = nums.size();
        
        int inds,inde;
        for(int i = 0;i < len-2;i++)
        {
            if(nums[i] >0)
                break;
            
            inds = i+1;
            inde = len-1;
            int sum = 0-nums[i];
            int di = nums[inds]-1;
            while(inds < inde)
            {
                if(nums[inds]+nums[inde] < sum)
                    inds++;
                else if(nums[inds]+nums[inde] > sum)
                    inde--;
                else if(nums[inds]+nums[inde] == sum)
                {
                    if(di != nums[inds])
                    {
                        temp.push_back(nums[i]);
                        temp.push_back(nums[inds]);
                        temp.push_back(nums[inde]);
                        res.push_back(temp);
                        temp.clear();
                        di = nums[inds];
                    }
                    inds++;
                    inde--;
                    
                }
            }
            while(i<len-3 && nums[i]==nums[i+1])
                i++;
            
        }
        
        return res;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值