题目
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的所有组合。
组合中的元素按非减序排列,组合不重复(任意两个组合的元素不同),组合的先后顺序无关。
暴力方法是n^3的,必然会超时。
n^2的步骤:
1、排序
2、循环,i从0~size-3;每次初始化:j=i+1,k=size-1。
此时在2中求num[j]+num[k]=-num[i],即可获得对应num[i]下的三数和为0的组合。问题便成为了之前的Two Sum问题,每次代价为O(n)。
注意:因为组合不能相同,所以每次取到符合要求的num[i]+num[j]+num[k]=0后改变j,k时需要保证新取的num[j]、num[k]与原来的不等;同理,改变i时也要使新取的num[i]与原来的不等。
代码:
class Solution {
public:
vector<vector<int> > threeSum(vector<int> &num) {
vector<vector<int>> ans;
int size=num.size();
if(size<3)
return ans;
sort(num.begin(),num.end());
vector<int> tri; //一组组合
int i=0,j=1,k=size-1;
while(j<k)
{
while(j<k) //Two Sum问题
{
if(num[i]+num[j]+num[k]==0)
{
tri.clear();
tri.push_back(num[i]);
tri.push_back(num[j]);
tri.push_back(num[k]);
ans.push_back(tri);
j++;
while(j<=k&&num[j]==num[j-1])
j++;
k--;
while(j<=k&&num[k]==num[k+1])
k--;
}
else if(num[i]+num[j]+num[k]<0)
j++;
else
k--;
}
i++;
while(i<size&&num[i]==num[i-1])
i++;
j=i+1;
k=size-1;
}
return ans;
}
};