思路:来自解题区
首先给这个向量排个序,然后先判断简单的情况,元素个数小于三直接返回空。
开始进入循环,固定当前数不变,如果当前所固定的数值大于0,对于递增向量来说不可能有和为0的三个数出现,直接break
如果当前数和前一个数相等,就说明与刚刚情况相同,已经考虑过了,continue
如果当前数与前一个数不同,定义两个指针,一个(left)指固定数的后一个数,另一个(right)指最后一个数,开始向中间挪动这两个指针,这时会出现三种情况:1.三个数之和大于0,那么right指针需要指向更小的数,则–right;2.和小于0,同理需要++left;3.等于0,找到满足的条件!所以保留下来,然后需要判断left之后的数,如果和此时left指的数值相等,就会重复,需要继续++left,同理对right进行判断是否需要–right。
当left>=right的时候这个循环结束了,开始对下一个数进行固定再判断。
要注意对坐标的判断,极容易出现溢出。
代码如下:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(),nums.end());//排序
vector<vector<int>> v;
vector<int> mid;
vector<int> mid;
if(nums.size()<3)
return v;
int left,right;
for(int i=0;i<nums.size()-2;++i)
{
if(nums[i]>0)//当前数为正,不可能找到和为0的组合
break;
if(i-1>=0&&nums[i]==nums[i-1])//会重复
continue;
left=i+1;
right=nums.size()-1;
while(left<right)
{
int sum=nums[i]+nums[left]+nums[right];
if(sum==0)
{
mid.push_back(nums[i]);
mid.push_back(nums[left]);
mid.push_back(nums[right]);
v.push_back(mid);
while((left+1)<nums.size()&&nums[left]==nums[left+1])//重复
++left;
while((right-1)>=0&&nums[right]==nums[right-1])
--right;
++left;
--right;
}
else if(sum>0)
--right;
else
++left;
}
}
return v;
}
};