题目链接:
题目:
Given an array
nums
of n integers, are there elements a, b, c innums
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;
}
};