一、题设
给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。
返回这三个数的和。
假定每组输入只存在恰好一个解。
二、基本思路
1.首先将数组按升序排序,其次第一层循环确定第一个数a,随后用双指针确定b、c在于[ i+1 , len(nums)]之间,如果三数相加结果 > target ,则右指针向左移动一格;同样如果三数相加结果 < target , 则左指针向右移动一格,每次有移动则记录比较最值,注意比较最值的步骤要放到开始,否则少记录了一次第一个数值。
2.通过左右指针移动的步频来优化算法:左右指针移动一个改为直接跳过相同值的数。
三、代码实现
def threeSumClosest(self, nums, target):
# 记录最小误差
min_radius = 999999
# 记录下标
a,b,c = -1,-1,-1
# n为长度
n = len(nums)
# 排序:升序
nums.sort()
for i in range(n):
# left确定左边界,right确定右边界
left,right = i + 1,n - 1
# 确定范围内三个相加等于target的数,i、left、right下标作为变量
while left < right:
if min_radius > abs(target - (nums[i] + nums[left] + nums[right])):
min_radius = abs(target - (nums[i] + nums[left] + nums[right]))
a,b,c = i,left,right
# 如果b+c不够target - i,即三数之和小于target
if nums[left] + nums[right] < target - nums[i]:
left += 1
# 如果b+c超出target - i,即三数之和大于target
elif nums[left] + nums[right] > target - nums[i]:
right -= 1
else:
return target
return nums[a] + nums[b] + nums[c]
优化后:
class Solution(object):
def threeSumClosest(self, nums, target):
# 记录最小误差
min_radius = 999999
# 记录下标
a,b,c = -1,-1,-1
# n为长度
n = len(nums)
# 排序:升序
nums.sort()
for i in range(n):
# left确定左边界,right确定右边界
left,right = i + 1,n - 1
# 确定范围内三个相加等于target的数,i、left、right下标作为变量
while left < right:
if min_radius > abs(target - (nums[i] + nums[left] + nums[right])):
min_radius = abs(target - (nums[i] + nums[left] + nums[right]))
a,b,c = i,left,right
# 如果b+c不够target - i,即三数之和小于target
# 相同的数不用比较了
if nums[left] + nums[right] < target - nums[i]:
left_v = left + 1
while nums[left_v] == nums[left] and left_v < right:
left_v += 1
left = left_v
left += 1
# 如果b+c超出target - i,即三数之和大于target
# 相同的数不用比较了
elif nums[left] + nums[right] > target - nums[i]:
right_v = right - 1
while nums[right_v] == nums[right] and right_v > left:
right_v -= 1
right = right_v
else:
return target
return nums[a] + nums[b] + nums[c]
四、效率总结
看似是没啥不同啊哈哈哈哈,但是确实是有优化的,优势可能要等数据量上升一个数量级才有明显的体现,最近好久没有刷力扣了,是因为最近的心情特别不好对自己的影响很大,总是沉不下心来做事情,就晓得刷刷抖音水水群啥的,在这里做一个检讨(反正也没人看我丢人也没事的)还有一个月开学,希望可以沉下心来多学一点,唉。。。加油吧!一定要明天见!