15. 三数之和

15. 三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != kj != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

**注意:**答案中不可以包含重复的三元组。

思路分析

双指针法: 两个循环 ,这个方法我们需要对数组进行排序。外层循环遍历给定的数组,搜集第一个元素。内层循环 leftright 指针缩小范围的同时,收集另外两个元素,因为答案不能包含重复的三元组,所以我们需要对满足条件的三元组进行去重。

如何对 leftright 进行初始化。

int left =0 , right = 0;
for(int i=0 ;i<nums.size() ; i++ ){
    left = i+1;
    right = nums.size()-1;
}

在这里插入图片描述
排序之后,如果三个数的和小于 0 ,说明三数相加太小,left ++ 。如果三个数的和大于0 right–。

当三个数之和 == 0 时。对结果集进行收集。

去重操作

我们需要对三个数进行去重 ,每当我们收集一个结果集之后 ,都要和之前的值进行比较 。

外层的 i (第一个元素) 判断 nums[i-1] == nums; 相等就继续循环

内层的 循环 nums[left +1] == nums[left] , nums[right-1] == nums[right] ,相等就跳过。不相等就收集

完整代码实现:

  vector<vector<int>> threeSum(vector<int>& nums) {
        //双指针法
        vector<vector<int>>ret;
       if(nums.size() == 0) return  ret;
        sort(nums.begin() ,nums.end());    // 排序,升序
        int left =0 , right = 0;
        int temp = 0;
        for(int i=0; i<nums.size()-2 ;i++){
            if(nums[i]> 0 ) break;
            left = i+1;
            right = nums.size()-1;
            //对第一个数进行去重
            if( i>0 && nums[i]==nums[i-1]) continue;
            while(left <right){
                temp = nums[i] + nums[left] + nums[right];   //三数相加
                //对范围进行压缩
                if( temp < 0 ){
                    left++;
                }else if(temp >0){
                    right--;
                }else{  //等于0
                    //收集一个结果集{
                    ret.push_back(vector<int>{nums[i] ,nums[left] ,nums[right]});
                    //去重操作
                    while(left < right && nums[left + 1] == nums[left]) left++;
                    while(left < right && nums[right - 1] == nums[right]) right--;

                    right--;
                    left++;
                }
            }
        } 
        return ret;
    }
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

零二年的冬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值