题目描述:
Given an array S of n integers, are there elements a,b,c inS 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.
For example, given array S = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]简单翻译就是找出数组中存在的三个不相同数的所有组合使得这三个数之和为0,并且保证所有组合不重复。
这道题的方法可以先给数组排序,再确定三个数中最小的数nums[i],然后使用两个指针j=i+1、k=n-1,从两头搜索,这样可以减少搜索次数,确定另外两个数使得这三个数之和为0,即为满足条件的组合。本题最大的难点在于保证组合不重复,因此采取以下方法:
一、先确定的数为nums[i],另外确定的数为nums[j]、nums[k],在保证i<j<k时才将这三个数push到结果向量中,可以避免nums[i]、nums[j]、nums[j]更换顺序导致重复。
二、在数组中可能存在多个值相同的数,为了避免nums[j]、nums[j]、nums[i]这三个数与值相同的其他数重复,可以分情况讨论:①避免nums[i]重复:如果i>0且nums[i]=nums[i-1]则i++;②避免nums[j]、nums[k]重复,如果nums[j]=nums[j-1]且j<k,则j++;如果nums[k]=nums[k+1]且k>j,则k--。
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(),nums.end());
vector<vector<int> > result;
if(nums.size()<3) return result;
for(int i=0;i<nums.size()-2;i++)
{
int n=nums.size();
while(nums[i]==nums[i-1]&&i>0) i++;
int j=i+1;
int k=n-1;
while(j<k)
{
if((nums[i]+nums[j]+nums[k])<0) j++;
else if((nums[i]+nums[j]+nums[k])>0) k--;
else if((nums[i]+nums[j]+nums[k])==0)
{
vector<int> temp;
temp.push_back(nums[i]);
temp.push_back(nums[j]);
temp.push_back(nums[k]);
result.push_back(temp);
j++;
k--;
while(nums[j]==nums[j-1]&&j<k) j++;
while(nums[k]==nums[k+1]&&k>j) k--;
}
}
}
return result;
}
};
由于多次判断使指针跳过重复的数值比较繁琐,而且容易出错,可以直接使用集合,重复的向量无法插入集合中,所以不用额外去判断重复值,使代码更加简单。
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(),nums.end());
set<vector<int> > result_set;
vector<vector<int> > result_vec;
if(nums.size()<3) return result_vec;
for(int i=0;i<nums.size()-2;i++)
{
int n=nums.size();
int j=i+1;
int k=n-1;
while(j<k)
{
if((nums[i]+nums[j]+nums[k])<0) j++;
else if((nums[i]+nums[j]+nums[k])>0) k--;
else if((nums[i]+nums[j]+nums[k])==0)
{
vector<int> temp;
temp.push_back(nums[i]);
temp.push_back(nums[j]);
temp.push_back(nums[k]);
result_set.insert(temp);
j++;
k--;
}
}
}
for(set<vector<int> >::iterator it=result_set.begin();it!=result_set.end();it++)
result_vec.push_back(*it);
return result_vec;
}
};