题目解析:
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
tip:
①如果三个数和为0,则必须有正有负,sort
②固定一个值,使用双指针的遍历方式确定其他两个值
③判断是否重复则判断是否相邻值相同即可
solution:
方案一: 手动去重
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
int num = nums.size();
sort(nums.begin(),nums.end());//如果和为0一定是有正有负
if(nums.empty() || nums.back()<0 || nums.front()>0) return {};//特殊情况判断
for(int k=0;k<num-2;k++)
{
if(nums[k]>0) break;
if(k>=1 && nums[k] == nums[k-1]) continue;//避免重复
int i = k+1,j=num-1;
int n = 0-nums[k];
while(i<j)
{
if(nums[i] + nums[j] == n)
{
res.push_back({nums[k],nums[i],nums[j]});
while(i<j && nums[i] == nums[i+1]) ++i;//避免重复
while(i<j && nums[j] == nums[j-1]) --j;
++i;
--j;
}
else
if(nums[i] + nums[j] < n) ++i;
else
--j;
}
}
return res;
}
};
方案二:set
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(),nums.end());
int len = nums.size();
if(nums.empty() || nums[0] > 0 || nums[len-1] < 0)//这里要首先判断是否为空
return {};
set<vector<int>> res;
for(int i=0;i<len-2;i++)
{
if(i>0 && nums[i] == nums[i-1]) continue;
int left = i+1;
int right = len-1;
while(left < right)
{
int sum = nums[i]+nums[left]+nums[right];
if(sum == 0)
{
vector<int> out{nums[i],nums[left],nums[right]};
res.insert(out);
while(left < right && nums[left] == nums[left+1]) ++left;
while(left < right && nums[right] == nums[right-1]) --right;
++left;
--right;
}
else
if(sum>0) --right;
else
++left;
}
}
return vector<vector<int>>(res.begin(),res.end());
}
};