栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

LeetCode 最接近的三数之和

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

LeetCode 最接近的三数之和

最接近的三数之和

题目来源:https://leetcode-cn.com/problems/3sum-closest

题目

给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。

例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.

与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
解题思路
  1. 数组排序 + 双指针;
  2. 对数组进行排序,初始化返回值 res 为 float('inf') 正无穷,用以比较赋值;
  3. 遍历数组,根据下面的步骤查找最接近的值:
    1. 先固定一个值 nums[i],定义双指针 L 和 R,分别指向固定值的下一位,以及最末尾的值;
    2. 考虑边界问题:
      1. 取包括固定值后续三位数之和(因为数组已排序,nums[i] + nums[L]+nums[L+1])为当前最小值 this_min,若是 this_min 比 target 大,表示后续的数值无论怎么组合,值都会比 this_min 大,所以这里直接比较 this_min 和 res 跟 target 的差值的绝对值,res 取较小的值,结束循环;
      2. 取固定值与末尾最后的两位数值之和为当下的最大值 this_max,若是 this_max 比 target 小,表示后续有更大可能接近 target 的值。这里也比较 this_max 和 res 跟 target 的差值绝对值,res 取较小值,然后跳过。
    3. 不存在边界问题时,在双指针之间进行遍历,计算固定值与双指针指向的值之和 three_sum;
    4. 当 three_sum 等于 target 时,直接返回 target;
    5. 当 three_sum 不等于 target 时,比较 three_sum 和 res 与 target 的差值绝对值,res 取较小值
    6. 当 three_sum 小于 target 时,左指针往右边移动,寻找更接近的值,注意去重;
    7. 当 three_sum 大于 target 时,右指针往左移动,寻找更接近的值,注意去重;
    8. 循环过程取固定值时,考虑避免取到重复的固定值。
    9. 时间复杂度:O(n2)O(n^2)O(n2)。
代码实现
class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
 # 先对数组进行排序
 nums.sort()
 nl= len(nums)
 # 将返回值初始化为正无穷
 res = float('inf')

 for i in range(nl-2):
     # 去重
     if i > 0 and nums[i] == nums[i-1]:
  continue
     # 定义双指针
     # 左边指针指向固定值下一位
     # 右边指针指向末尾
     L, R = i+1, nl-1

     # 处理边界的问题
     this_min = nums[i] + nums[L] + nums[L+1]
     # 数组已经排序,将连续三位数字作为当下最小值
     # 若是当下最小的值比 target 还大,后面的数值与 target 的差值会越来越大
     # 比较当前最小值和返回值各自与 target 差值的大小,赋值之后跳出循环
     if this_min > target:
  if (this_min - target) < abs(res - target):
      res = this_min
  break
     
     # 将当前值与最末尾两位数值之和作为当前的最大值
     # 若是当下最大值比 target 小,这里可以确定后续可能还有更接近的值
     # 所以比较当下最大值和返回值与 target 差值大小,赋值后,直接跳过
     this_max = nums[i] + nums[R-1] + nums[R]
     if this_max < target:
  if (target - this_max) < abs(res - target):
      res = this_max
  continue
     
     # 不满足上面的条件时
     # 在两指针的区间进行遍历
     while L < R:
  # 计算固定值与双指针对应值三者之和
  three_sum = nums[i] + nums[L] + nums[R]
  # 若结果等于 target,直接返回 target
  if three_sum == target:
      return target
  # 比较 three_num 和 res 分别与 target 的差值,res 取较小值
  if abs(three_sum - target) < abs(res - target):
      res = three_sum
  # three_num 小于 target 时,左指针往右移动,寻找更接近的值
  if three_sum < target:
      L += 1
      # 去重
      while L < R and nums[L] == nums[L-1]:
   L += 1
  # three_num 大于 target 时,右指针往左移动,寻找更接近的值
  else:
      R -= 1
      # 去重
      while L < R and nums[R] == nums[R+1]:
   R -= 1
 
 return res
 
实现结果

题外话

本题主要需要考虑的点在于边界问题的处理。这一块的处理,能够很大程度上快速给出结果值。


以上就是本篇的主要内容。


欢迎关注微信公众号《书所集录》

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号