1 题目描述
2 解题思路:排序+双指针
大体上思路和文巾解题 15. 三数之和_刘文巾的博客-CSDN博客是一样的
我们对整个数组进行升序排序。然后:
1)假设数组的长度为 n,我们先枚举 a,它在数组中的位置为 i;
2)为了防止重复枚举,我们在位置 [i+1, n) 的范围内枚举 b 和 c。
借助双指针,我们就可以对b和c的枚举的过程进行优化。初始时,bp指向位置 i+1,即左边界;c指向位置 n-1,即右边界。在每一步枚举的过程中,我们用 a+b+c来更新答案,并且:
1--如果a+b+c≥target,那么就将c 向左移动一个位置;(减小a+b+c的值)
2--如果a+b+c<target,那么就将 b向右移动一个位置。(增大a+b+c的值)
和15一样,枚举a,b,c 中任意元素并移动指针时,可以直接将其移动到下一个与这次枚举到的不相同的元素,减少枚举的次数。
class Solution:
def threeSumClosest(self, nums: List[int], target: int) -> int:
nums.sort()
#对数组进行排序
ret=10**7
#我们需要的和结果最接近的值
l=len(nums)
for a in range(l):
#如果当前a的值和前一个值是一样的,那么可以直接跳过。因为这一个a对应的值之前已经考虑过了
if(a!=0 and nums[a-1]==nums[a]):
continue
b=a+1
c=l-1
while(b<c):
#结束条件不能是b≤c,因为要三个不一样的数
if(b!=a+1 and nums[b-1]==nums[b]):
b+=1
continue
#相同的b不用考虑
if(c!=l-1 and nums[c+1]==nums[c]):
c-=1
continue
#相同的c不用考虑
tmp=nums[a]+nums[b]+nums[c]
if(abs(ret-target)>abs(tmp-target)):
ret=tmp
#看当前的值是不是比目前最接近的值更接近,如果是的话更新最接近的值
if(tmp>target):
c-=1
#减少下一个tmp的值
elif(tmp==target):
return tmp
#相等,差距为0,直接返回
else:
b+=1
#增大下一个tmp的值
return(ret)