15. 三数之和
难度中等3966
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]输出:[[-1,-1,2],[-1,0,1]]
示例 2:
输入:nums = []输出:[]
示例 3:
输入:nums = [0]输出:[]
提示:
- 0 <= nums.length <= 3000
- -105 <= nums[i] <= 105
思路
找任意两个数的排列组合,第三个数补0(桶排序,找第三个数)
[0,0,0] | 细节错误i<0 or i<=0,没有考虑到重复数字情况 |
[-2,0,1,1,2] | 两重循环没有遍历到每个值 |
[82597,-9243,62390,……] | -10^5 <= nums[i] <= 10^5 题目设置的值的范围不对 |
[0,0,……此处省略3000个0] | 超时报错 if(i>0&&nums[i]==nums[i-1])设限 |
[34,55,79,28,46,33,2,48,31,-3,84,71,52,-3,93,15,21,-43,57,-6,86,56,94,74,83,-14,28,-66,46,-49,62,-11,43,65,77,12,47,61,26,1,13,29,55,-82,76,26,15,-29,36,-29,10,-70,69,17,49] | 剪枝,剪的缺少了一部分 |
小技巧
去重之set,vector互换
set<vector<int>> st(res.begin(), res.end());
res.assign(st.begin(), st.end());
代码
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int i,j;
int temp[210000]={0};
vector<vector<int>> res;
if(nums.size()<3)
return res;
sort(nums.begin(),nums.end());
//设置桶
for(int k=0;k<nums.size();k++)
{
printf("%d,",nums[k]);
if(nums[k]>=0)
temp[nums[k]]++;
else
temp[100000-nums[k]]++;//-1位于10001
}
printf("\n");
//两两匹配,找桶
for(i=0;i<nums.size();i++)
{
//剪枝
if(i>0&&nums[i]==nums[i-1])
{
continue;
}
j=nums.size()-1;
if(nums[i]<0)
{
temp[100000-nums[i]]--;
}
else
temp[nums[i]]--;
for(j=nums.size()-1;j>i;j--)
{
vector<int> a;
// printf("%d,%d,%d\n",nums[i],nums[j],nums[i]+nums[j]);
if(nums[j]<0)
temp[100000-nums[j]]--;
else
temp[nums[j]]--;
//分情况,找temp
if((nums[i]+nums[j])>0)
{
if(nums[i]+nums[j]>100000)
break;
if(temp[100000+nums[i]+nums[j]]>0)//假设结果为1,找-1
{
a.push_back(nums[i]);
a.push_back(nums[j]);
a.push_back(0-nums[i]-nums[j]);
sort(a.begin(),a.end());
res.push_back(a);
}
}
else if((nums[i]+nums[j])<0)
{
if(abs(nums[i]+nums[j])>100000)
break;
if(temp[abs(nums[i]+nums[j])]>0)//假设结果为-1,找1
{
a.push_back(nums[i]);
a.push_back(nums[j]);
a.push_back(abs(nums[i]+nums[j]));
sort(a.begin(),a.end());
res.push_back(a);
}
}
else if((nums[i]+nums[j])==0&&temp[0]>0)//假设结果为-1,找1
{
a.push_back(nums[i]);
a.push_back(nums[j]);
a.push_back(0);
sort(a.begin(),a.end());
res.push_back(a);
}
if(nums[j]<0)
temp[100000-nums[j]]++;
else
temp[nums[j]]++;
}
if(nums[i]<0)
temp[100000-nums[i]]++;
else
temp[nums[i]]++;
}
//去重
set<vector<int>> st(res.begin(), res.end());
res.assign(st.begin(), st.end());
return res;
}
};