题目:
给定一个包括 n 个整数的数组 nums
和 一个目标值 target
。找出 nums
中的三个整数,使得它们的和与 target
最接近。返回这三个数的和。假定每组输入只存在唯一答案。
例如,给定数组 nums = [-1,2,1,-4], 和 target = 1. 与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
答案:
class Solution:
def threeSumClosest(self, nums: List[int], target: int) -> int:
nums.sort()
list2=[]
if len(nums)<3:
return None
ans=nums[0]+nums[1]+nums[2]
for i in range(len(nums)):
start=i+1
end=len(nums)-1
while start<end:
sum1=nums[i]+nums[start]+nums[end]
if abs(target-ans)>abs(target-sum1):
ans=sum1
if target>sum1:
start+=1
elif target<sum1:
end-=1
else:
return ans
return ans
解释:
有三个数,使用暴力枚举的方法,需要三层for循环,时间复杂度达到O(n三次方)。给数组排序以及定义两个指针。排序是方便后面指针的移动,使用两个指针移动,一个从左边开始,一个从右边开始,效率会比较高。
为什么排序之后,一左一右的指针就可以考虑完所有情况。这是因为数组是排序好的,先固定i的值,再确定遍历的初始值,使start=i+1,end=len(nums)-1。sum=nums[i]+nums[start]+nums[end]就是一个情况,将这个值与之前定义的返回值ans判断,判断条件是谁更接近,把更接近的给ans。因为本质是看target与sum的接近程度,target比sum要大,需要放大sum的值,即把start指针往右移(数组是排序好的,越往右越大),同理,target比sum要小,需要缩小sum的值,将end往左移。还有一个很重要的原则,每次只能改变一个。直到start和end相遇,这时候i改变,开始下一轮的循环。