LeetCode15.三数之和

题目描述
给你一个包含 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的另外两个数存入数组;然后继续下一个第一个数。。。
需要考虑的是去重问题。因此每挪动一次指针,要满足指针指到的位置是下一个不重复的数字。

具体实现:

  1. 数组排序
  2. 固定第一个数a→确定第二个数的指针b(从左到右)和第三个数的指针c(从右到左)→判断此时加和的状态→
    可以确定的是,因为数组已经排好序:
    1)三数之和大于0时,指针c往左挪到下一个不重复数字,找更小的数;
    2)等于0时记录下这一组数据,指针b往右挪找下一组;
    3)小于(等于)0时,如果指针c再往左找到的只能是和更小的数,不会再有和为0的情况,因此指针b往右挪找(和)更大的数
  3. 直到a找到边界

一些可以考虑的情况:
1.数组元素小于3
2.a,b,c的边界值:a从0到倒数第二个;b从a+1算起;c从len(nums)-1算起;保证b<c,b、c就不会出现索引异常的情况。
3.指针不重复的条件

数组排序;

'''
三数之和
'''
def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        ans = []
        n=len(nums)
        if (not nums or n<3):
            return []
    
        nums.sort() #排序 
        
        for a in range(n):
            if nums[a]>0:
                break
            if a>=1 and nums[a]==nums[a-1]: #找到a的固定点,并保证不与前面重复
                continue

            c = n-1	#每新开一轮a,b、c就要重新定义
            b=a+1
            while b<c:	#指针b的循环
                if b>a+1 and nums[b]==nums[b-1]:
                    b+=1
                    continue    #直到找到不与前面重复的指针b

                while b < c: 	#指针c的循环
                    if c<n-1 and nums[c]==nums[c+1]:
                        c-=1    
                        continue  #直到找到不与后面重复的指针c

                    #以下判断和的情况,决定不同情况下指针的操作
                    if nums[a]+nums[b]+nums[c]==0:  #等于0时,记录一组数据
                        ans.append([nums[a], nums[b], nums[c]]) 
                        b+=1        #挪动指针b,找下一组可能性
                        break
                    elif nums[a]+nums[b]+nums[c] > 0:   
                        c-=1    #比0大时,指针c还能往左挪
                    else:   #和小于0,指针c再往左所有的和都比0小,因此挪b
                        b+=1
                        break

        return ans
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值