题目:
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)
思路:
思路一是递归的方式用01背包问题来解决。但是需要检查冲突,时间开销比较大。思路二是三层循环,首先对数组排序,前两层是完全的循环,最后一层是二分查找,考虑到有连续的相同值,时间上还可以再优化。
代码:
思路一:
class Solution {
public:
vector<vector<int> >* v;
vector<vector<int> > threeSum(vector<int> &num) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
v = new vector<vector<int>>();
if(num.size() < 3)
{
return *v;
}
sort(num.begin(), num.end());
vector<int> res;
add(num, 0, res);
return *v;
}
void add(vector<int> &num, int i, vector<int> res)
{
if(i < num.size())
{
if(res.size() == 2 && res[0] + res[1] + num[i] == 0)
{
vector<int> tmp;
tmp.push_back(res[0]);
tmp.push_back(res[1]);
tmp.push_back(num[i]);
bool duplicate = false;
for(int k = 0; k < v->size(); k++)
{
if(v->at(k) == tmp)
{
duplicate = true;
break;
}
}
if(!duplicate)
v->push_back(tmp);
}
else if(res.size() == 2 && res[0] + res[1] + num[i] != 0)
{
add(num, i+1, res);
}
else if(res.size()<2)
{
add(num, i+1, res);
res.push_back(num[i]);
add(num, i+1, res);
}
}
}
};
思路二:
class Solution {
public:
vector<vector<int> >* v;
vector<vector<int> > threeSum(vector<int> &num) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
v = new vector<vector<int>>();
if(num.size() < 3)
{
return *v;
}
sort(num.begin(), num.end());
for(int i = 0; i < num.size()-2; i++)
{
if(i > 0 && num[i] == num[i-1])
{
continue;
}
for(int j = i+1; j < num.size()-1; j++)
{
if(j > i+1 && num[j] == num[j-1])
{
continue;
}
int left = j+1;
int right = num.size()-1;
while(left<=right)
{
int mid = left + ((right-left)>>1);
if(num[i] + num[j] + num[mid] == 0)
{
vector<int> tmp;
tmp.push_back(num[i]);
tmp.push_back(num[j]);
tmp.push_back(num[mid]);
v->push_back(tmp);
break;
}
else if(num[i] + num[j] + num[mid] > 0)
{
right = mid - 1;
}
else
{
left = mid + 1;
}
}
}
}
return *v;
}
};