1.题目
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
- Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
- 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)
从一个数组中找到三个数,是这三个数的和等于0,找到所有符合条件的三个数,并没有重复。
2.思路
很自然的可以想到,可以把找3个数的问题化解为找两个数的问题,即找到a+b=-c;
我们先对数组进行排序。先从最小的数开始选,nums[i](起初i=0).
令target=-nums[i];,然后从比i大的数列中开始找,设置head=i+1为数列的头部,tail=len-1为数列的尾部,两个指针向中间遍历,直至找到;
注意返回值中不需要重复的答案,所以搜索的时候如果和前一个值相等则直接跳过,指针接着偏移。
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> ans;
int len=nums.size();
if(len<3) return {};
sort(nums.begin(),nums.end());
int i=0;
while(i<len-2)
{
int target=-nums[i];
int head=i+1,tail=len-1;
while(head<tail)
{
if(nums[head]+nums[tail] == target) //找到了符合条件的三个数
{ ans.push_back(vector<int>{nums[i],nums[head],nums[tail]});
do{tail--;} while(nums[tail] == nums[tail+1] && head<tail); //去重
do{head++;} while(nums[head] == nums[head-1] && head<tail);
}
else if(nums[head]+nums[tail] > target)
{
do{tail--;} while(nums[tail] == nums[tail+1] && head<tail);
}
else
{
do{head++;} while(nums[head] == nums[head-1] && head<tail);
}
}
do{i++;} while(nums[i]==nums[i-1] && i<len-2);
}
return ans;
}
};