数组进行升序排序后,从左向右固定某一个数,left/right两个指针分别指向另外两个数,left指向最左端,right指向最右端,对三个数进行求和,如果小了就把left指针向右移,如果大了就把right指针向左移,如果和刚好是0则记录并且继续探索(left向右移且right向左移时可能存在多组解),参考了Java的一个版本。
class Solution { public: vector<vector<int> > threeSum(vector<int> &num) { vector<vector<int> > rst; if(num.size() < 3) { return rst; } sort(num.begin(), num.end()); for(int i=0;i<num.size()-2;i++) { if(num[i] > 0) { break; } if(i>0 && num[i]==num[i-1]) { continue; } int left = i+1; int right = num.size() - 1; while(left < right) { int sum = num[i] + num[left] + num[right]; if(sum > 0) { //和超了,最右边指针向左移以获取较小的数; right--; }else if(sum < 0) { //和不够,最左边指针向右移以获取较大的数; left++; }else { //和刚好为0,但可能不止一组满足条件,左指针向右,右指针向左移时可能仍然满足条件; vector<int> tmp; tmp.push_back(num[i]); tmp.push_back(num[left]); tmp.push_back(num[right]); rst.push_back(tmp); //继续看是否还有满足条件的; //左指针跳过重复数字; while(left < right && num[left]==num[left+1]) { left++; } //右指针跳过重复数字; while(left < right && num[right] == num[right-1]) { right--; } left++; right--; } } } return rst; } };