力扣:15. 三数之和(双指针)

【题解】

双指针

注:

1.定义一个二位数组存储结果集

2.对输入数组进行升序

3.去重(主要考虑三个数的去重。 a, b ,c, 对应的就是 nums[i],nums[left],nums[right])

(1)对a去重:

判断 nums[i] 与 nums[i + 1]是否相同,还是判断 nums[i] 与 nums[i-1] 不一样,一个是对后一个判断,一个是对前一个判断

使用nums[i]==nums[i+1],例如{-1, -1 ,2} 这组数据,当遍历到第一个-1 的时候,判断 下一个也是-1,那这组数据就pass了。将会漏掉-1,-1,2 这种情况。

我们要做的是 不能有重复的三元组,但三元组内的元素是可以重复的!

nums[i] == nums[i-1]当遍历到 第一个 -1 的时候,只要前一位没有-1,那么 {-1, -1 ,2} 这组数据一样可以收录到 结果集里。

(2)b与c的去重

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++){
            //因为数组是升序,当i(第一个数)>0时,后面两个数肯定大于零,所以三个数相加不可能等于零,直接返回空的result
            if(nums[i] > 0){
                return result;
            }
            //i>0是防止数组下标出现负数情况,使用nums[i]==nums[i+1]将会漏掉-1,-1,2 这种情况,所以使用nums[i] == nums[i-1]
            if(i > 0 && nums[i] == nums[i-1]){
                continue;//去重a
            } 
            int left = i + 1;
            int right = nums.size() - 1;
            //当right=left的时候,指向的是同一个元素,那么就变成了二元组相加,而不是三元组相加
            while(right > left){
                if(nums[i] + nums[left] + nums[right] > 0) right--;//三数之和大于零
                else if(nums[i] + nums[left] + nums[right] < 0) left++;//三数之和小于零
                 //三数之和等于零
                else{
                    //先返回一个结果集     
                    result.push_back(vector<int>{nums[i], nums[left], nums[right]});
                    // 去重逻辑应该放在找到一个三元组之后,对b 和 c去重
                    while(right > left && nums[left] == nums[left+1]) left++;
                    while(right > left && nums[right] == nums[right-1]) right--;

                    // 找到答案时,双指针同时收缩
                    left++;
                    right--;
                }
            }
        }
        return result;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值