https://leetcode.com/problems/3sum/
套路比较常见了,最重要的是去重。还是没法一次通过。
class Solution { public: vector<vector<int>> threeSum(vector<int>& a) { vector<vector<int>> ans; int n = a.size(); if(n < 3) return ans; sort(a.begin(),a.end()); for(int i = 0; i < n - 2; i++) { int target = - a[i]; for(int j = i + 1, k = n - 1; j < k; ) { int sum2 = a[j] + a[k]; if(sum2 == target) { vector<int> tmp{a[i],a[j],a[k]}; ans.push_back(tmp); // 这一行做完以后,a[j]依然等于a[j-1]。 while(j+1 < n && a[j+1]==a[j]) j++; j++; while(k-1 >= 0&& a[k-1]==a[k]) k--; k--; } else if(sum2 < target) { j++; } else { k--; } } //这一步并不总是执行的,只是走到所有的重复的最后。 while(i+1 < n && a[i+1] == a[i]) i++; } return ans; } };
去重的原理要好好想一下:
比如 -2 -2 -2 0 1 1 1 1 2
第一次i选中-2的时候,后面的组合有0 2,1 1.
这之后,如果再选第二个-2作为第一个数的话,后面依然会产生0 2 , 1 1,就发生了重复。
因为,如果第一次在集合A中找2,第二次相当于在A的子集中找2。第二次找出的结果肯定是第一次结果的子集。
所以,第一次选-2以后,第二次选应该找到第一个不是-2的数。这样去重。