思路:这道题与双指针法类似,使用三指针法 头尾各一个 中间一个来回扫,重点是如何剪枝,想了会我也只能剪出下面这样子了,但还是只超5%;
评论区笑傻:
#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;
vector<vector<int>> threeSum(vector<int> &nums)
{
vector<vector<int>> res;
if (nums.size() < 3)
return res;
int length = nums.size();
//三指针法 头指针一个指0 尾指针两个指length-2 和length-1
int oneP = 0;
int twoP;
int threeP = length - 1;
set<vector<int>> temp; //先放 temp 集合用于去重
sort(nums.begin(), nums.end()); //从小到大排序 NlgN
while (oneP < threeP - 1)
{
twoP = oneP + 1;
for (; twoP < threeP; twoP++)
{
int sum = nums[oneP] + nums[twoP] + nums[threeP];
if (sum == 0) //如果和为零 插入 , 且此时右边两个指针都不用往左移,因为左移之后只可能小于0 or 重复
{
vector<int> vec;
vec.push_back(nums[oneP]);
vec.push_back(nums[twoP]);
vec.push_back(nums[threeP]);
temp.insert(vec);
continue;
}
else if (sum > 0)
{
twoP--;//保持twoP不动
threeP--;
}
else //sum<0
{
continue;
}
}
threeP=length-1;//第三指针归位
oneP++;
}
//把temp集合里的vector都放res中
for (auto v : temp) //集合中的每个vector
{
res.push_back(v);
}
return res;
}
int main()
{
vector<int> test;
test.push_back(-1);
test.push_back(0);
test.push_back(1);
test.push_back(2);
test.push_back(-1);
test.push_back(-4);
vector<vector<int>> result;
result = threeSum(test);
for (auto a : result)
{
for (auto b : a)
{
cout << b << " ";
}
cout << endl;
}
test.clear();
test.push_back(-2);
test.push_back(0);
test.push_back(1);
test.push_back(1);
test.push_back(2);
result = threeSum(test);
for (auto a : result)
{
for (auto b : a)
{
cout << b << " ";
}
cout << endl;
}
return 0;
}
如有建议,感谢指明!!!