【leetcode】15. 三数之和。 「双指针」

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

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

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
示例 2:

输入:nums = []
输出:[]
示例 3:

输入:nums = [0]
输出:[]

提示:

0 <= nums.length <= 3000
-10^5 <= nums[i] <= 10^5

思路:

本题可以使用双指针的方法,但是首先遇到一个问题,就是这道题有3个数,所以我们可以首先把第一个数拎出来,这不就剩下两个指针了吗。
i为第一个数,j,k分别是第二,三个数,j为i下一个数,k为最后一个数。j和k是左右边界。
再来分析一下题目,因为不能是重复的组合,所以首先我们可以先进行排序,这样就不会轻易出现数字相同但是顺序不同的情况了。如果三者之和大于0就把k往左移,如果小于0,就把j往右移,直到两者相遇然后换下一个i来重置j和k重新进行查找。找到了等于0的时就把对应的数存到res中,
但是还要注意一个问题,避免重复,所以就是不能出现连续两个相同的数在前后两次查找中,所以在i,j++,k–的时候都要先进行判断,如果移动后的数与原数相等,就跳过该数,继续往下走,直到不同为止。

代码区:

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        int i=0;
        sort(nums.begin(),nums.end());//首先进行从小到大排序,避免出现重复
        vector<vector<int>> res;//等于二维数组
        int n=nums.size();//n为nums的长度
        if(n<3)return {};//如果n小于3,说明不可能满足条件,直接输出空
        while(i<n-1){//将第一个数单独领出来,创造出双指针j,k的条件
            int j=i+1;int k=n-1;//j为i下面一个数,k为最后一个数
            while(j<k){//当两指针没有相遇时
                if(nums[i]+nums[j]+nums[k]<0)//如果三数相加小于0说明应该使j再大一点,因为是排序好的
                    j++;
                else if(nums[i]+nums[j]+nums[k]>0)//如果大于0就要将k小一点
                    k--;
                else{//如果刚好等于0就是满足条件
                    res.push_back(vector<int>{nums[i],nums[j],nums[k]});//推入res中
                    j++;k--;//范围继续变小
                    while(j<k&&nums[j]==nums[j-1])//因为不能出现重复的,所以在这里如果遇到了相同的数就要跳过
                        j++;
                    while(j<k&&k<n-1&&nums[k]==nums[k+1])//同上
                        k--;
                }
            }
            while(i<n-1&&nums[i]==nums[i+1])//i这个单独拎出来的数也要考虑不能重复,所以如果等于上一个数就要跳过
                    i++;    
            i++;//i+1,开始另一个组合的循环j,k
        }
        return res;//输出结果
    }
};

新手上路,有错请指正;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Khalil三省

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

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

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

打赏作者

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

抵扣说明:

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

余额充值