超级详细的题解与代码备注:(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;
}
};
京公网安备 11010502036488号