[LeetCode] 16.最接近的三数之和 最优解@Python

该博客主要介绍了LeetCode第16题的解决方案,目标是找到数组中三个整数的和,使得它们的和最接近给定的目标值。博主首先给出了一个粗略的O(n^2)解法,然后详细阐述了一个优化的O(nlogn)解法,通过排序和双指针来减少时间复杂度,确保找到最接近目标值的三数之和。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

Example:
Given array nums = [-1, 2, 1, -4], and target = 1.
The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).

粗略解法

  • 参考三数之和可以首先得到一个粗略解法
  • 同样是先对nums排序,只不过:
    • 处理的是和为target而非0的三数和问题
    • 对于每次相加得到的total,需要进行一个最接近判断
class Solution(object):
    def threeSumClosest(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        nums.sort()
        closest = nums[0]+nums[1]+nums[2]
        
        for i in range(len(nums)-2):
            left, right = i+1, len(nums)-1
            
            while left < right:
                total = nums[i] + nums[left] + nums[right]
                
                if total == target:
                    return target
                
                if abs(total-target) < abs(closest-target):
                    closest = total
                    
                if total < target:
                    left += 1
                elif total > target:
                    right -= 1
        
        return closest

最优解法

  • 之前的粗略解法复杂度是 O ( n 2 ) O(n^2) O(n2),还可以做进一步的优化(14-24行):
    1. nums[i]+nums[left]+nums[left+1]为当前及之后时刻所有和中最小值(nums经过排序是按大小升序的),如果这个加和大于target,那么意味着之后所有时刻的加和都会更加大于target,因此只需比较closest、target、当前加和的值,并break即可(14-18行)
    2. nums[i]+nums[right]+nums[right-1]为该循环所有加和中最大值,若这个值仍小于target,那么意味当前循环所有加和更加小于target,因此只需比较closest、target、当前加和的值,并进入下一个循环即可(20-24行)
    3. 剩余部分与之前的解法相同(26-36行)
class Solution(object):
    def threeSumClosest(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        nums.sort()
        closest = nums[0]+nums[1]+nums[2]
        
        for i in range(len(nums)-2):
            left, right = i+1, len(nums)-1
            
            min_value = nums[i] + nums[left] + nums[left + 1]
            if min_value > target:
                if abs(min_value-target) < abs(closest-target):
                    closest = min_value
                break
            
            max_value = nums[i] + nums[right] + nums[right - 1]
            if max_value < target:
                if abs(max_value-target) < abs(closest-target):
                    closest = max_value
                continue
            
            while left < right:
                total = nums[i] + nums[left] + nums[right]
                if total == target:
                    return target
                if abs(total-target) < abs(closest-target):
                    closest = total
                if total < target:
                    left += 1
                elif total > target:
                    right -= 1
        return closest

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值