解题思路:(python3)
由于小白能力有限,首先想到的还是暴力解题法……在排序的数组中进行遍历寻找、作比较,排除重复元素所浪费的执行时间(因为是双指针形式,所以相邻的大小相等的元素在同一指针下即视为“重复”)。值得注意的是,在第一次作比较的时候,mindiff与diff为了得到diff,在初始化mindiff的时候特意赋值为无穷大。
class Solution:
def threeSumClosest(self, nums: List[int], target: int) -> int:
n = len(nums)
if n < 3:
return 0
if n == 3:
return sum(nums)
nums.sort()
mindiff = float("inf")
closestSum = 0
for i in range(n):
if i > 1 and nums[i] == nums[i-1]:
continue
L = i + 1
R = n - 1
while(L < R):
Sum = nums[i] + nums[L] + nums[R]
diff = Sum - target
if abs(diff) < mindiff:
mindiff = abs(diff)
closestSum = Sum
if diff == 0:
return closestSum
elif diff < 0:
L += 1
while(L<R and nums[L]==nums[L-1]):
L +=1
else:
R -= 1
while(L<R and nums[R]==nums[R+1]):
R -= 1
return closestSum
PS:
其实在第一次尝试失败的时候用的不是这个方法,但是思想是一致的。不同之处在于第一种失败的方法中,用的是指针所指的三数之和与target的大小做分类点,但是后来越想越复杂所以没有成功,而上述做法是按照差值与0的大小做分类点,优点是分类的时候更清晰明了,简单。我把第一次尝试的时候的失败代码也粘贴过来吧,恳请大家热心留言赐教,按照这个原本的思路如何修正小白的这个第一次失败的尝试。
class Solution:
def threeSumClosest(self, nums: List[int], target: int) -> int:
if len(nums)<3:
return 0
if len(nums)==3:
return sum(nums)
nums.sort()
_Minn=float("inf")
for i in range(len(nums)):
left=i+1
right=len(nums)-1
while left<right:
if nums[i]+nums[left]+nums[right]==target:
break
if nums[i]+nums[left]+nums[right]>target:
right=right-1
_Min=nums[i]+nums[left]+nums[right]-target
_Min=min(_Min,_Minn)
reduc=abs((nums[i]+nums[left]+nums[right])-target)
Sum=nums[i]+nums[left]+nums[right+1] if _Min<reduc else (nums[i]+nums[left]+nums[right])
_Minn=_Min if _Min<reduc else reduc
'''
想尝试在一次比较中筛选出来最接近的三数之和以及相应的差值
将其保留用做下一次的比较,但是明显是失败的……
下面的else用的是同一个思想
'''
else:
left=left+1
_Min=target-nums[i]+nums[left]+nums[right]
_Min=min(_Min,_Minn)
reduc=abs((nums[i]+nums[left]+nums[right])-target)
Sum=nums[i]+nums[left-1]+nums[right] if _Min<reduc else (nums[i]+nums[left]+nums[right])
_Minn=_Min if _Min<reduc else reduc
return Sum