目录
网站原题
力扣:16. 最接近的三数之和
给你一个长度为
n
的整数数组nums
和 一个目标值target
。请你从nums
中选出三个整数,使它们的和与target
最接近。返回这三个数的和。
假定每组输入只存在恰好一个解。
示例 1:
输入:nums = [-1,2,1,-4], target = 1 输出:2 解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。示例 2:
输入:nums = [0,0,0], target = 1 输出:0提示:
3 <= nums.length <= 1000
-1000 <= nums[i] <= 1000
-104 <= target <= 104
分析解答
双指针算法:
- 先对数组元素按大小进行排序,得到sort_List;
- 对数组中的 len(sort_List)-2 个元素(为了避免下面求固定元素sort_List[i]的左邻元素sort_List[i+1]时发生索引溢出),使用for循环迭代三个数中的一个加数;
- 第一次遍历时,固定该加数(即数组的首个元素sort_List[0]),使用左指针和右指针分别存储该固定加数的左邻元素和数组的最右端元素的索引值,如下图所示:
- 如果此时三个数的和大于目标值,由于sort_List[right-1]<sort_List[right],只需要将右指针往左移,如果此时三个数的和小于目标值,由于sort_List[left+1]>sort_List[left],只需要将左指针往右移。
- 后续的迭代中,重复此操作。当左指针=右指针时,完成了对数组所有剩余元素的遍历。在这个过程中记录距离目标值最小的和,即为所求最优值:
class Solution:
def threeSumClosest(self, nums: List[int], target: int) -> int:
# 对数组进行排序
sort_List = sorted(nums)
# 初始化离目标值最近的最优值
best = float("inf") # float("inf")表示正负无穷大,也可以用一个极大的数代替
# 遍历其中一个元素
for i in range(0,len(sort_List)-2):
left = i+1
right = len(sort_List)-1
# 固定这一个元素,移动双指针
while left != right:
cur = sort_List[i]+sort_List[left]+sort_List[right]
# 记录最优值
if abs(cur-target) < abs(best-target):
best = cur
# 三数和大于目标值时,右指针左移,减小总和
elif cur > target:
right -= 1
# 三数和小于目标值时,左指针右移,增大总和
elif cur < target:
left += 1
# 三数和等于目标值时,达到理想最优,直接返回目标值
else:
return target
return best
改进算法:
在前面代码的基础之上,还可以对不必要遍历的环节进行剪枝,进一步减小算法的时间复杂度,具体实现如下:
待续....