题目链接:https://leetcode-cn.com/problems/3sum/
解答1:暴力穷举:
class Solution {
public:
int binarySearch(vector<int> nums, int target)
{
int left = 0;
int right = nums.size() - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (nums[mid] == target) {
return mid;
}
else if (nums[mid] < target) {
left = mid + 1;
}
else if (nums[mid] > target) {
right = mid - 1;
}
}
return -1;
}
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int> >reti;
if(nums.size()<=2)
return reti;
vector<int> temp;
vector<int> xiaoyu0;
vector<int> dengyu0;
vector<int> dayu0;
sort(nums.begin(),nums.end());
for(auto i=0;i<nums.size();i++)
{
if(nums[i]<0)
xiaoyu0.push_back(nums[i]);
else if(nums[i]==0)
dengyu0.push_back(nums[i]);
else if(nums[i]>0)
dayu0.push_back(nums[i]);
}
sort(dayu0.begin(),dayu0.end());
if(dengyu0.size()>=3)
{
temp.push_back(0);
temp.push_back(0);
temp.push_back(0);
if(reti.size()==0)
reti.push_back(temp);
else if(reti.back()!=temp)
{
reti.push_back(temp);
}
temp.clear();
}
if(dayu0.size()>0 && xiaoyu0.size()>0 && dengyu0.size()>0)
{ //包含0,一个正数,一个负数
auto len1=xiaoyu0.size();
auto len2=dayu0.size();
if(len1<len2)
{
for(auto i=0;i<len1;i++)
{
int rflag=binarySearch(dayu0,(0-xiaoyu0[i]));
if(rflag!=-1)
{
temp.push_back(xiaoyu0[i]);
temp.push_back(0);
temp.push_back(dayu0[rflag]);
if(reti.size()==0)
reti.push_back(temp);
else if(reti.back()!=temp)
{
reti.push_back(temp);
}
temp.clear();
}
}
}
else
{
for(auto i=0;i<len2;i++)
{
int rflag=binarySearch(xiaoyu0,(0-dayu0[i]));
if(rflag!=-1)
{
temp.push_back(xiaoyu0[rflag]);
temp.push_back(0);
temp.push_back(dayu0[i]);
if(reti.size()==0)
reti.push_back(temp);
else if(reti.back()!=temp)
{
reti.push_back(temp);
}
temp.clear();
}
}
}
}
if(xiaoyu0.size()>=2 && dayu0.size()>0)
{
//两个负数,一个正数的情况
for(auto i=0;i<xiaoyu0.size()-1;i++)
{
for(auto j=i+1;j<xiaoyu0.size();j++)
{
int rflag=binarySearch(dayu0,(0-xiaoyu0[i]-xiaoyu0[j]));
if(rflag!=-1)
{
temp.push_back(xiaoyu0[i]);
temp.push_back(xiaoyu0[j]);
temp.push_back(dayu0[rflag]);
if(reti.size()==0)
reti.push_back(temp);
else if(reti.back()!=temp)
{
reti.push_back(temp);
}
temp.clear();
}
}
}
}
if(xiaoyu0.size()>0 && dayu0.size()>=2)
{
//两个正数,一个负数的情况
for(auto i=0;i<dayu0.size()-1;i++)
{
for(auto j=i+1;j<dayu0.size();j++)
{
int rflag=binarySearch(xiaoyu0,(0-dayu0[i]-dayu0[j]));
if(rflag!=-1)
{
temp.push_back(xiaoyu0[rflag]);
temp.push_back(dayu0[i]);
temp.push_back(dayu0[j]);
if(reti.size()==0)
reti.push_back(temp);
else if(reti.back()!=temp)
{
reti.push_back(temp);
}
temp.clear();
}
}
}
}
vector<vector<int> >reti2;
//reti2=reti;
for(auto i=0;i<reti.size();i++)
{
temp = reti[i];
if(reti2.size()==0)
reti2.push_back(temp);
else if(find(reti2.begin(),reti2.end(),temp)==reti2.end())
{
reti2.push_back(temp);
}
temp.clear();
}
return reti2;
}
};
上述解答太暴力了,以至于超时了。解答2,遍历+双指针。
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int> >reti;
//考虑不满足的条件的情况,返回空
if(nums.size()<=2)
return reti;
vector<int> temp;
sort(nums.begin(),nums.end());
for(auto i=0;i<nums.size()-2;i++)
{
auto j=0,k=0;
if(i==0 || ((i>=1) && (nums[i]!=nums[i-1])))
{
j=i+1;
k=nums.size()-1;
while(j<k)
{
if((nums[i]+nums[j]+nums[k])==0)
{
temp.push_back(nums[i]);
temp.push_back(nums[j]);
temp.push_back(nums[k]);
reti.push_back(temp);
temp.clear();
// 去掉重复元素
while(j<k && nums[j]==nums[j+1])
{
j++;
}
while(j<k && nums[k]==nums[k-1])
{
k--;
}
j++;
k--;
}
else if((nums[i]+nums[j]+nums[k])<0)
j++;
else
k--;
}
}
}
return reti;
}
};
想了很久,看到了有讨论说双指针的思路,才豁然开朗。