本题目可以选用两种方法做
1. 暴力解法
2.排序+双指针
这里着重讲第二种方法
写题思路:
将原数组排序,这样的话,每个筛选出来的,不会存在组合相同顺序不同。
1.定义i 作为第一个数的下标 使用while循环(i!=nums.size()-2) 为什么-2? 因为最多为倒数第三个
2.第一层循环的处理,如果nuns[i]>0 那么后面的j和k相加就不可能为0 所以直接return
long long l=static_cast<long long >(nums[left]); 为防止溢出
3. 第二层循环,如果和小于0 那么吧left++ 如果大于0 right--,如果恰好满足 先判断下一个是不是和当前的数一样大小,如果一样大,left++,因为如果不加会出现重复问题,右边也是同理。
下面第一层循环也是这个道理,如果nums[i+1] ==nums[i] 会产生重复解
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
if(nums.size()<3)
return {};
vector<vector<int> > ans;
sort(nums.begin(),nums.end());
int i=0;
while(i<nums.size()-2)
{
if(nums[i]>0)
return ans;
int left=i+1,rigjt=nums.size()-1;
while(left<rigjt)
{
long long l=static_cast<long long >(nums[left]);
long long r=static_cast<long long >(nums[rigjt]);
long long p=static_cast<long long >(nums[i]);
if(l+r>0-p)
rigjt--;
else if(l+r<0-p)
left++;
else if(l+r+p==0)
{
ans.push_back({nums[i],nums[left],nums[rigjt]});
while(left<rigjt&&nums[left]==nums[left+1])
left++;
while(left<rigjt&&nums[rigjt]==nums[rigjt-1])
rigjt--;
left++;
rigjt--;
}
}
while(i<nums.size()-2&&nums[i]==nums[i+1])
i++;
i++;
}
//-1 -1 0 1
return ans;
}
};
暴力做法在下面 三层循环
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> target;
//sort(nums.begin(),nums.end());
for(int i=0;i<nums.size()-2;i++)
{
for(int j=i+1;j<nums.size()-1;j++)
{
for(int k=j+1;k<nums.size();k++)
{
if(nums[i]+nums[j]+nums[k]!=0)
continue;
int p=0;
for(;p<target.size();p++)
{
if(target[p][0]==nums[i]&&target[p][1]==nums[j]&&target[p][2]==nums[k])
{
break;
}
}
if(p==target.size())
target.push_back({nums[i],nums[j],nums[k]});
}
}
}
return target;
}
};