先排序,然后固定第一个元素,然后再用剩余的两个左右夹逼。时间O(n^2),空间O(1)。
注意排序后,相邻的元素有可能重复,如果去除重复元素是关键,见代码。
参考:http://fisherlei.blogspot.hk/2013/01/leetcode-3-sum-solution.html
class Solution {
public:
vector<vector<int> > threeSum(vector<int> &num) {
vector<vector<int> > result;
if(num.size() < 3) return result;
sort(num.begin(), num.end());
auto last = num.end();
for(auto a=num.begin(); a < prev(last, 2); ++a)
{
auto left = next(a);
auto right = prev(last);
while(left < right)
{
if(*a + *left + *right < 0) left++;
else if(*a + *left + *right > 0) right--;
else
{
result.push_back({*a, *left, *right});
left++;
right--;
while(left<right && *left == *prev(left)) left++; //skip duplicate
while(left<right && *right == *next(right)) right--; //skip duplicate
}
}
while(*a == *next(a)) a++; //skip duplicate
}
return result;
}
};
8.23代码,优化了去重部分:
class Solution {
public:
vector<vector<int> > threeSum(vector<int> &num) {
vector<vector<int> > result;
if(num.size() < 3) return result;
std::sort(num.begin(), num.end());
for(int i=0; i<num.size()-2; i++)
{
//remove duplicate
if(i>0 && num[i] == num[i-1])
continue;
int first = num[i];
int left = i+1;
int right = num.size()-1;
while(left < right)
{
//remove duplicate
if(left > i+1 && num[left] == num[left-1])
{
left++;
continue;
}
//remove duplicate
if(right < num.size()-1 && num[right] == num[right+1])
{
right--;
continue;
}
if(num[left]+num[right]+first > 0)
right--;
else if(num[left]+num[right]+first < 0)
left++;
else
{
vector<int> res(3);
res[0] = first;
res[1] = num[left];
res[2] = num[right];
result.push_back(res);
right--;
left++;
}
}
}
//std::sort(result.begin(), result.end());
//result.erase(unique(result.begin(), result.end()), result.end());
return result;
}
};