三数之和 & 最接近的三数之和

1、Leetcode15.三数之和 链接
在这里插入图片描述
这道题是一个典型的双指针,可能会有一个疑问,三个数,为什么会是双指针啊,最近好久没有做题了,当看到这个题的时候,我的想法也是用三个指针去遍历,但是发现其实有一个指针可以是固定的,接下来看一下这个题的答案就知道了。

思考:
看到这道题的时候,我第一个想法就是先将nums进行一个升序排序
第二个想法就是判断特例,有哪些特例呢?
1)如果nums的长度小于等于2,那么直接返回空列表
2)如果指针移动时,发现当前所指向的元素和上一个元素是一样的,那么应该跳过

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        # 1、特判,对于数组长度n,如果数组为null或者数组长度小于3,返回[]
        # 2、对重复数组:跳过,避免出现重复解
        # 令左指针L= i+1, 右指针R=n-1,当L<R时,执行循环:
        #   当nums[i] +nums[L]+nums[R] == 0,执行循环,判断左界和右界是否和下一位置重复,去除重复解,并同时将L,R移到下一位置,寻找新的解
        #   若和大于0,说明nums[R]太大,R左移
        #   若和小于0,说明nums[L]太小,L右移
        # 复杂度分析:时间复杂的 O(n^2),数组排序O(NlogN),遍历数组O(n),双指针遍历O(n),总体O(NlogN)+O(n^2)
        nums.sort()
        n = len(nums)
        res = []
        if not nums or n<3:
        	return res
        for i in range(n):
        	# 如果第一个指针都大于0了,那么必不可能有三数之和为0的情况了。
        	if nums[i]>0:
        		return res
        	if i>=1 and nums[i]==nums[i-1]: # 当i>0,即从i=1开始就需要判断,避免出现重复解
        		continue
        	l,r = i+1,n-1
        	while l<r:
        		if nums[i]+nums[l]+nums[r]==0:
        			res.append(nums[i],nums[l],nums[r])
        			while l<r and nums[l]==nums[l+1]:
        				l+=1
        			while l<r and nums[r]==nums[r-1]:
        				r-=1
        			l+=1
        			r-=1
        		elif nums[i]+nums[l]+nums[r] >0:
        			r-=1
        		else:
        			l+=1
        return res 

2、Leetcode16.最接近的三数之和 链接
在这里插入图片描述
可以看到这道题可以演化成三数之和,所以说三数之和可以当作这道题的一个特例,我们完全可以用三数之和的思路解决这道题,但是我们并不需要判断左右指针已经重复问题,如果你想缩短运行时间,那么确实可以多做一些判定。
话不多说,直接上代码思路:

class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
    nums.sort()
    ans = sum(nums[:3]) # 这里先计算前三个元素做一个初始对比量
    n = len(nums)
    for i in range(n):
    	l,r = i+1,n-1
    	while l<r:
    		tmp = nums[i]+nums[l]+nums[r]
    		if tmp == target:
    			return tmp
    		elif tmp < target:
    			l+=1
    		else:
    			r-=1
    		if abs(tmp-target)<abs(ans-target):
    			ans = tmp
    return ans
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值