LeetCode 算法题库【16】——最接近的三数之和

最接近的三数之和

题目描述:

timu

解题思路:
  • 第一种:这道题和上一个题的那个三数之和的思路很像,所以这个解法也是排序 + 双指针的写法,大体上思路和三数之和一样,也要去重,简化,然后求最后的三数之和和题目所给target的差值,如果差值等于零,那么直接返回这个和即可,如果大于零或者小于零,则就继续缩小范围看看能不能使差值diff更加接近于 0 ,最后返回更加接近于 0 的数。
class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        lens = len(nums)
        nums.sort()
        # 设最小差为无限大
        mini = float('inf')
        closesum = 0
        if lens == 3:
            return sum(nums)
        else:
            for i in range(lens-2):
                if i > 1 and nums[i] == nums[i-1]:
                    continue
                L = i + 1
                R = lens - 1
                while L < R:
                    Sum = nums[i] + nums[L] + nums[R]
                    diff = Sum - target
                    if abs(diff) < mini:
                        mini = abs(diff)
                        closesum = Sum
                    if diff == 0:
                        return Sum
                    elif diff > 0:
                        R -= 1
                        while L<R and nums[R] == nums[R+1]:
                            R -= 1
                    else:
                        L += 1
                        while L<R and nums[L] == nums[L-1]:
                            L += 1
        return closesum

1

  • 第二种:这个方法也是和上一道三数之和类似,用了二分法来得到一个初始值,然后也是双指针的方法,和target比较,这里有一点我感到特别神奇,就是这里的最后双指针的增加或者减少不需要再用ifelse了,可以通过比较运算符的特点,成立就会返回1,不成立返回0,减少了很多代码量,很值得学习。
class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        nums.sort()
        res = float('inf')
        lens = len(nums)
        for i in range(lens - 2):
            L = max(i + 1,bisect.bisect_left(nums, target - nums[lens-1] - nums[i], i+1, lens-1)-1)
            R = lens-1
            while L < R and res != target:
                Sum = nums[i] + nums[L] + nums[R]
                res = min(res, Sum, key=lambda x: abs(x - target))
                L = L + (Sum < target)
                R = R - (Sum > target)
        return res

2

  • 第三种:这个是在第一种方法的基础上做了些改进,这里把整体分成三部分来看,先是直接用minimaxi得到最小的和最大的三数之和,然后和target进行比较,如果说最小的和都大于target或者最大的和都小于target,则这个和就是最接近的三数之和,答案也就出来了。除去了最大和最小的和,然后就是对中间的这些三数之和进行讨论,这里的解法就和第一种方法没有差别了,该去重也要去重,遇到绝对值更小的就赋值回给res,最后返回最小的绝对值res
class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        nums.sort()
        res = float('inf')
        lens = len(nums)
        for i in range(lens-2):
            if i > 0 and nums[i] == nums[i-1]: 
                continue
            L = i + 1
            R = lens - 1
            mini = nums[i] + nums[L] + nums[L+1]
            maxi = nums[i] + nums[R-1] + nums[R]
            if mini > target:
                if abs(mini - target) < abs(res - target):
                    res = mini
                break
            if maxi < target:
                if abs(maxi - target) < abs(res - target):
                    res = maxi
                continue   
            while L < R:
                Sum = nums[i] + nums[L] + nums[R]
                if Sum == target:
                    return target
                if abs(Sum - target) < abs(res - target):
                    res = Sum
                if Sum < target:
                    L += 1
                    while L < R and nums[L] == nums[L-1]: 
                        L += 1
                if Sum > target:
                    R -= 1
                    while L < R and nums[R] == nums[R+1]: 
                        R -= 1
        return res

3

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值