题目:
给你一个长度为
n
的整数数组nums
和 一个目标值target
。请你从nums
中选出三个整数,使它们的和与target
最接近。返回这三个数的和。
假定每组输入只存在恰好一个解。
来源:力扣(LeetCode)
链接:力扣
示例:
示例 1:
输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
示例 2:输入:nums = [0,0,0], target = 1
输出:0
解法:
首先将nums排序,接着遍历nums(外层循环),取出每个数(num),target更新为target-num,题目变成在nums(去除num)中找两个数最接近target。然后进入算法,利用双指针的思想,设x1指向nums头部,x2指向nums尾部(内层循环),如果nums[x1]+nums[x2]<target,x1+=1,说明此时两数之和太小,由于nums已升序排序过,所以nums[x1]<=nums[x2],左侧元素小,越往右越大,所以通过增加x1来扩大两数之和。如果>target,同理,x2-=1,如果=target,说明找到3个数和为target,则返回target。每一轮如果!=target,还需要更新与target的差值(delta),delta初值设为13001(很大的一个数),如果|num+nums[x1]+nums[x2]-target|<|delta|(<左边绝对值中内容设为t3),说明当前的3个数之和更接近target,更新delta为t3,最后返回target+dleta,循环的终止条件是x1=x2。
代码:
class Solution: def threeSumClosest(self, nums: List[int], target: int) -> int: delta = 10000 + 3000 + 1 nums.sort() for index, num in enumerate(nums): obj = target - num if index == 0: new_nums = nums[1:] elif index == len(nums) - 1: new_nums = nums[:-1] else: new_nums = nums[:index] + nums[index + 1:] x1 = 0 x2 = len(new_nums) - 1 while x1 != x2: if (t2 := new_nums[x1] + new_nums[x2]) < obj: delta = t3 if abs((t3 := num + new_nums[x1] + new_nums[x2] - target)) < abs(delta) else delta x1 += 1 elif t2 > obj: delta = t4 if abs((t4 := num + new_nums[x1] + new_nums[x2] - target)) < abs(delta) else delta x2 -= 1 else: return target return target + delta