Leecode 15 .三数之和
先对数组做排序
用双指针法,for循环中 , left = i+1,right = nums.size() -1;
for循环中,首先对i进行去重,因为需要返回不重复的三元组,
内层的while循环中,循环条件为 left < right,同样的,我们也需要对left 和 right 进行去重,那么如何去重呢,是进入循环时直接去重,还是找到一个三元组以后再去重呢?
考虑一个刚开始便是[0,0,0]的三元组,若是再while循环刚开始对它进行去重的话,会导致left >= right ,从而漏过了这种情况,所以我们需要在找到一个三元组后,再进行去重。
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result ;
sort(nums.begin(),nums.end());
for(int i = 0; i < nums.size() ;i++) // 三元组, 至少三个数字
{
if(nums[i] > 0) return result; // 第一个数字大于0,则不可能存在这样的三元组
//对 i 去重
if(i > 0 && nums[i] == nums[i-1]) continue; // 下标为0时还是正常进入的,从1开始判断去重逻辑
int left = i + 1;
int right = nums.size() -1;
while( left < right)
{ int sum = nums[i] + nums[left] + nums[right];
if(sum>0){
right --;
}
else if(sum < 0)
{
left ++;
}
else
{
result.push_back(vector<int>{nums[i],nums[left],nums[right]});
// 在这里对left 和 right 进行去重
while(left < right && nums[left] ==nums[left+1])//移动到left的下个元素与当前left不同
{left++;}
while(right > left && nums[right -1] == nums[right])
{right--;}
// 同时收缩,因为前面的去重已经保证left++ 和left不同, right-- 和right不同了
left ++;
right --;
}
}
}
return result;
}
};