LeetCode_16_中等_最接近的三数之和
文章目录
- 1. 题目
- 2. 思路及代码实现(Python)
- 2.1 排序 + 双指针
1. 题目
给你一个长度为 n n n 的整数数组 n u m s nums nums 和 一个目标值 t a r g e t target target。请你从 n u m s nums nums 中选出三个整数,使它们的和与 t a r g e t target target 最接近。
返回这三个数的和。
假定每组输入只存在恰好一个解。
示例 1:
输入: n u m s = [ − 1 , 2 , 1 , − 4 ] , t a r g e t = 1 nums = [-1,2,1,-4], target = 1 nums=[−1,2,1,−4],target=1
输出:2
解释:与 t a r g e t target target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
示例 2:
输入: n u m s = [ 0 , 0 , 0 ] , t a r g e t = 1 nums = [0,0,0], target = 1 nums=[0,0,0],target=1
输出:0
提示:
- 3 < = n u m s . l e n g t h < = 1000 3 <= nums.length <= 1000 3<=nums.length<=1000
- − 1000 < = n u m s [ i ] < = 1000 -1000 <= nums[i] <= 1000 −1000<=nums[i]<=1000
- − 1 0 4 < = t a r g e t < = 1 0 4 -10^4 <= target <= 10^4 −104<=target<=104
2. 思路及代码实现(Python)
2.1 排序 + 双指针
类似于前文,求三数之和的《LeetCode_15_中等_三数之和》,可以考虑l对数组排序后用双指针进行快速搜索。而本题不是求和为固定值的三数,转为求最接近目标值 t a r g e t target target 的三元组,即三数之和与目标值的差值的绝对值最小。
同样是先排序(升序),当固定了第一个值时,如果三个数之和大于等于 t a r g e t target target,此时增加第二个值只会增大三数之和,离目标值越来越远,因此当达到了这个边界时,不会有固定第一个、第三个值之后的其他组合,此时移动第二个值无效,因此出现该情况移动第三个值的索引;若三数之和达到另一个边界,小于目标值,此时固定第一第二个值时,移动第三个值不会比当前的组合更好,因此可以移动第二个值。
时间复杂度显然为 O ( N 2 ) O(N^2) O(N2),空间复杂度为 O ( N ) O(N) O(N),相比于题15的三数之和,区别在于需要根据三树之和与目标值的差值来更新最优的和,而逻辑基本一致。
class Solution:def threeSumClosest(self, nums: List[int], target: int) -> int:nums.sort()n = len(nums)best = 10**7# 根据差值的绝对值来更新答案def update(cur):nonlocal bestif abs(cur - target) < abs(best - target):best = cur# 枚举 afor i in range(n):# 保证和上一次枚举的元素不相等if i > 0 and nums[i] == nums[i - 1]:continue# 使用双指针枚举 b 和 cj, k = i + 1, n - 1while j < k:s = nums[i] + nums[j] + nums[k]# 如果和为 target 直接返回答案if s == target:return targetupdate(s)if s > target:# 如果和大于 target,移动 c 对应的指针k0 = k - 1# 移动到下一个不相等的元素while j < k0 and nums[k0] == nums[k]:k0 -= 1k = k0else:# 如果和小于 target,移动 b 对应的指针j0 = j + 1# 移动到下一个不相等的元素while j0 < k and nums[j0] == nums[j]:j0 += 1j = j0return best
执行用时:578 ms
消耗内存:16.52 MB
参考来源:力扣官方题解