排序加hash,O(n^2)复杂度
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int size=nums.size();
if(size<3) return {
};
sort(nums.begin(),nums.end());
unordered_map<int,int> hashmap;
for(int p:nums) {
hashmap[p]++;}
vector<vector<int>> res;
for(int i=0;i<size-2;++i)
{
if(nums[i]>0)
break;
int x=nums[i];
for(int j=i+1;j<size-1;++j)
{
int y=nums[j];
int z=-x-y;
if(hashmap.find(z)!=hashmap.end())
if(z<x||z<y)
break;
else if((z==0&&hashmap[z]>2)||(z!=0&&z==y&&hashmap[z]>1)||(z!=y)){
res.push_back({
x,y,z});
while(j<size-1&&nums[j]==y)
++j;
j--;
}
}
while(i<size-2&&nums[i]==x)
++i;
--i;
}
return res;
}
};
再后来我想用左右双指针向中间靠拢,但发现不行,这样如法处理前后互为相反数的情况,这样的情况下,当然还有相邻两个数间隔比较大的特殊情况也无法处理;
while(back-1>front)
{
int x=nums[front],y=nums[back];
int z=-x-y;
if(hashmap.find(z)!=hashmap.end()&&z<=y&&z>=x)
if((hashmap[z]>2&&z==y&&z==x&&y==x))
{
res.push_back({
x,z,y});}
else if(hashmap[z]>1&&(z==y||z==x))
{
res.push_back({
x,z,y});}
else if(z!=x&&z!=y)
{
res.push_back({
x,z,y});}
if(abs(x)<abs(y))
while((back-1>front)&&nums[back]==y)
--back;
else
while((back-1>front)&&nums[front]==x)
++front;
}
看了下答案,发现原来可以把双指针用到第二层循环里,需要注意的是,每个循环里面都要小心数组越界
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int size=nums.size();
if(size<3) return {
};
sort(nums.begin(),nums.end());
vector<vector<int>> res;
int i=0;
while(i<size-2)
{
if(nums[i]>0) break;
int front=i+1,back=size-1,x=nums[i];
while(front<back)
{
int y=nums[front],z=nums[back];
if(0==(x+y+z))
res.push_back({
x,y,z});
if(y+z+x>0)
while((front<back)&&z==nums[back])
--back;
else
while((front<back)&&y==nums[front])
++front;
}
while(i<size-2&&nums[i]==x)
++i;
}
return res;
}
};