题目描述
思路
我们如果是乱序的数组,如何集合去重?很困难!所以我们先想排序,再进行接下来的操作.
如果使用for三重循环,肯定是会超时的.考虑固定第一个指针,第二个指针在第一个指针右边,不断变大,为了最后的a+b+c=0(此时的a是固定的数值), 随着b的变大,c一定是会变小的,也就是说,b和c的选择就不是先选择b,再选择c的,我们可以同时选择!令b=a+1(指针意义上的加一!),c=nums
[size-1],那么大体思路上就已经解决了.
细节问题
对于-1,-1,-1,0,1,2,4这个数组,我们如果做才能使得结果中只有一组{-1,-1,2}这个数据呢?对于i,j两个指针,我们为了避免元素,对于第一个指针,只需要第一个重复元素即可,但是对于第二个指针,我们不能只是简单通过nums[begin]=nums[begin-1]来判断是否跳过,比如-1,-1,2,如果这样做,第二个直接就跳过了第二个"-1",答案就少了一个,所以我们要给第二个指针加上一个约束条件,第二个指针下标减去第一个指针下标要大于一.
代码实现
#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
using namespace std;
class Solution {
public:
vector<vector<int> > res;
void twoSum(vector<int>& nums,int begin,int end,int target,int index) {
int flag = 0;
while (begin < end) {
if (nums[begin] + nums[end] > target) {end--;}
else if (nums[begin] + nums[end] < target) { begin++; }
else {
if (begin>index+1&&nums[begin]==nums[begin-1]) { //这里也是我没想到的.我们每一次比较,都是和上一个元素进行比较
begin++;
continue;
}
res.push_back({ nums[index] ,nums[begin],nums[end]});
begin++;
end--;
}
}
}
vector<vector<int>> threeSum(vector<int>& nums) {
int i, j, k;
int size = nums.size();
sort(nums.begin(), nums.begin() + nums.size());
for (i = 0; i < size;++i) {
if (i > 0 && nums[i] == nums[i - 1]) continue; //这个是我没有想到的...同样的还是和上一个元素进行比较
twoSum(nums, i + 1, size - 1, -nums[i], i);
}
return res;
}
};
[注]index是第一个指针,begin是第二个指针,end是第三个指针.