三数之和(简单易理解)

该文介绍了如何解决寻找数组中三个元素之和为零的问题,使用了排序和双指针的方法。首先排除数组长度小于3的情况,然后对数组排序,通过固定一个元素并用双指针移动来找到三元组,同时避免了重复解。在过程中特别注意了指针去重的策略。
摘要由CSDN通过智能技术生成

三数之和 (简单易理解)

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

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

示例:

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

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

难点:本题的难点在于如何去除重复解
使用方法:双指针
基本思路:固定一个位置,另外两个位置使用双指针去移动
执行步骤

  • 去掉特殊情况,对于数组长度小于3,数组为空的情况,直接返回 []
  • 数组排序,按照从小到大排序(为了方便剪枝,去除重复情况)
  • 遍历排序后的数组,此时的i即为固定位置,每次的遍历都是使用一次双指针
    • 如果当前i指向的元素都大于0,则不可能出现=0的三个数了(因为数组是排序后的,当前i是三个数中的最小值)
    • i遍历到重复元素则跳过,避免出现重复解
    • 令左指针l=i+1,右指针r=n-1 (左指针指向当前遍历i的下一位;右指针指向最后,从后往前遍历),当l<r时 ,执行循环
      • sum=nums[i]+nums[l]+nums[r],如果等于0,将结果对应的索引位置的值加入结果集中,别忘了此时要对左右指针去重、移位
      • 如果结果sum大于0,将右指针左移
      • 如果结果小于0,将左指针右移

可执行代码

class Solution():
    def threeSum(self,nums):
        n=len(nums)
        result=[]
        #如果数组为null或者长度小于3,返回[]
        if nums==None or n<3:
            return []
        #对数组进行排序
        nums.sort()  #该方法没有返回值,但是会对列表的对象进行排序
        #遍历排序后的数组
        for i in range(n):
            #如果当前i指向的元素都大于0,则不可能出现=0的三个数了
            if nums[i]>0:
                return result
            # i 重复元素则跳过
            if i > 0 and nums[i]==nums[i-1]:
                continue
            #令左指针l=i+1,右指针r=n-1 
            l=i+1
            r=n-1
            # 当l<r时 ,执行循环
            while(l<r):
                sum=nums[i]+nums[l]+nums[r]
                # 如果等于0,将结果对应的索引位置的值加入结果集中
                if sum==0:
                    result.append([nums[i],nums[l],nums[r]])
                    #在将左指针和右指针移动的时候,先对左右指针的值,进行判断; 如果重复,直接跳过; 
                    #去重,因为 i 不变,当此时 l取的数的值与前一个数相同,所以不用在计算,直接跳
                    while l < r and nums[l]==nums[l+1]:
                        l+=1
                    #去重,因为 i不变,当此时 r 取的数的值与前一个相同,所以不用在计算
                    while l < r and nums[r]==nums[r-1]:
                        r-=1
                    #将 左指针右移,将右指针左移
                    l+=1
                    r-=1
                # 如果结果大于0,将右指针左移
                elif sum>0:
                    r-=1
                #如果结果小于0,将左指针右移
                else:
                    l+=1

        return result

注意

  1. 固定位置i和左右指针的去重操作不一样
    固定位置: nums[i]==nums[i-1]
    左指针: nums[l]==nums[l+1]
    右指针: nums[r]==nums[r-1]
    原因:这是因为固定位置去重时,如果使用nums[i]==nums[i+1],那么会导致丢失一些非重复的出现情况
    例如:数组 [1,1,2]
    使用nums[i]==nums[i+1]这种方式:在遍历第一个1时,会将后一个1判断为重复,直接跳过[1,1,2]这种情况;
    使用nums[i]==nums[i-1]这种方式:在遍历第一个1时,不会将后一个1判断为重复,添加[1,1,2]这种情况到结果集

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值