题解 | #数组中相加和为0的三元组#
数组中相加和为0的三元组
http://www.nowcoder.com/practice/345e2ed5f81d4017bbb8cc6055b0b711
超级详细的题解与代码备注:(C++代码)
思路:
首先判断给点数组的大小是否<3 小于3的话则直接返回一个空的结果.
对整个数组进行排序:
寻找一个基准值target(基准值为从数组的第1个元素到倒数第三个元素),然后再从基准值target的后面找到两个数组等于-target,这个时候是不是就是求两数之和啦。
好的,那这个时候利用双指针解法,代码上都有详细备注,我相信大家肯定都能看懂的。
class Solution { public: vector<vector<int> > threeSum(vector<int>& num) { vector<vector<int>> ans; if (num.size() < 3) //个数不满足的时候明显不符合要求,返回结果。 return ans; sort(num.begin(), num.end()); //对给定的数组进行排序 for (int i = 0; i < num.size() - 2; i++) //-2是因为保证从i开始剩下的数组长度>=3 { if (num[i] > 0) //基准值大于0 ,后面查找的两个数肯定不存在。 break; int j = i+1, k = num.size() - 1; //j从i后面的第一个数开始尝试,k从数组最后一个位置开始尝试 int target = -num[i]; //寻找两个数相加为target while (j<k) { if (num[j] + num[k] < target) //说明寻找的两个数比目标值小,所以尝试更大的一种情况。 j++; else if (num[j] + num[k] > target)//说明比目标值大,尝试更小的一种情况 k--; else //相等的状况。 { vector<int> temp = {num[i],num[j],num[k]}; ans.push_back(temp); //target=num[j]+num[k] target一定时,确定了num[j]、num[k] 其中一个那么另外一个就确定了 那么得到的肯定就会重复 //所以下面两行代码是为了去掉当target一定时 重复的情况 while (num[j] == num[j + 1] && j+1<k) j++; while (num[k] == num[k - 1] && k-1>j) k--; ++j; --k; //相等的话这两个数就不再使用了(已经用过了)。 } } //为了去除target重复的情况,试想一下,当num[i]=x的时候, i后面所有相加=-x 的两个数已经全部求出来了。 //那再求i+1 后面的必然是上面所求的子集。 这里依旧还是需要判断i,因为防止后面再次判断num[i+1]的时候产生越界。 while (num[i] == num[i + 1] && i < num.size() - 2) i++; } return ans; } };