【LeetCode刷题】15.三数之和(超细节)

题目:15.三数之和

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意: 答案中不可以包含重复的三元组。

示例:

给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

解题思路

这里主要是用了一种固定的套路:双指针

  • nums排序(从小到大)。
  • 双指针
    1>.先定义3个指针,一个固定指针i,两个左右指针L,R
    2>.令i固定数组的最左边,作为新动态数组的左边界,即i=0;
  • 同时,L=i+1,R=len(nums) -1,即分别指向新数组的两端;
  • 用i遍历数组,作为外循环,不断的将左边界向右推进,逐渐缩小新数组的长度;
  • 判断 sum=nums[i]+nums[L]+nums[R] 的大小;
  • sum==0, 符合要求,存入res,之后,L+1,R-1;
  • sum<0, L+1;
    (因为数组是从小到大排序过的,当sum<0,三个数整体来说是偏小的,自然要让三数中最小的数nums[L]变大,即指针L向右移动)
  • sum>0,R-1;
    (同理,sum偏大,就让最大的值nums[R]变小)

动画

在这里插入图片描述

代码(Python)

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        res=[]
        #错误判断,数组长度小于3,直接返回
        if(not nums or len(nums)<3):
            return []
        nums.sort()
        res=[]
        #外循环
        for i in range(len(nums)-2): 
        	#初始化左右指针
            L=i+1
            R=len(nums)-1   
            #边界判断       
            while L<R:  
                sum = nums[i]+nums[L]+nums[R]  
                #符合要求,向res赋值,同时左右指针向内推进                    
                if sum ==0:
                    res.append([nums[i],nums[L],nums[R]])
                    L=L+1
                    R=R-1
                #sum偏小,L向右移动
                elif sum < 0:
                    L=L+1
                #sum偏大,L向左移动
                else:
                    R=R-1
        return res

相信有的小伙伴已经发现了。当数组中有重复的元素时,其实是可以排除掉的。
更改代码如下:

代码(Python)

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        res=[]

        if(not nums or len(nums)<3):
            return []
        nums.sort()
        res=[]

        for i in range(len(nums)-2): 
        	#nums[i]都>0,三数都是正数,sum不可能=0
            if(nums[i]>0):
                return res
            #排除重复的nums[i]
            if(i>0 and nums[i]==nums[i-1]):
                continue
            L=i+1
            R=len(nums)-1  
            while L<R:  
                sum = nums[i]+nums[L]+nums[R]                   
                if sum ==0:
                    res.append([nums[i],nums[L],nums[R]])
                    L=L+1
                    R=R-1
                elif sum < 0:
                    L=L+1
                else:
                    R=R-1
                #排除重复的nums[L],nums[R]
                while(L<R and nums[L]==nums[L+1]):
                    L=L+1
                while(L<R and nums[R]==nums[R-1]):
                    R=R-1

        return res

总结

好了,关于双指针的问题,就到这里了。leetcode咱也是刚开始刷,我准备接下来多做几道关于双指针的题目,有时间也会继续做出动画的!最后,有错误遗漏的地方欢迎大家指正!完结撒花~
有兴趣的也可以康康我的下一篇:最接近的三数之和
在这里插入图片描述

后续

同时,贴上咱的个人博客,欢迎客官大老爷们来访~
青枫阁

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值