题目介绍
今天是这道题是数组部分的第四题,整个题库的第16题,最接近的三数之和
我们的目的是在一个给定数组中找到三个数,让这三个数的加和最接近于target,这道题和我们上一次说过的三数之和问题非常类似,都是通过三个指针来解决问题。下面我们来说一下具体的思路
题目分析
首先我们看一下这道题的特点:它不要求我们返回索引之类的数据,只要求我们返回数据的值即可,那么我们就可以随意折腾我们的这个数组。根据我们之前做过的题,我们很快就能想到可以对这个数组进行升序排序,这样我们的指针在移动之前就会有具体的移动方向(与target值做笔记,具体参考三数之和)
我们首先先声明一个无穷量:
res = float("inf") #每次的(sum - target)先于res作比较
我们每次算出target与sum之间的差距就会与这个res进行比较.最终找出最小的res,将它所对应的sum的三个数组加入我们的答案数组中。
由于这个算法目前是无序的,所以我们需要先对他进行排序,让它按照升序排列:
nums.sort()
然后在最外层循环设置一个指针,这个指针的范围是range(数组长度-2),因为我们有三个指针,所以第一个指针最远是在数组的倒数第三个位置。
内存循环中,我们声明另外两个指针,一个是L,一个是R,这两个指针分别初始化在i+1与n-1的位置,如果发现当前三个指针所指向的数字和为sum<target,则L指针右移(找更大的数字),反之如果sum>target,则R指针左移。每次算出res = |target - sum|作为我们每次比较的标准。
注意:为了节约时间,我们每次移动指针后如果碰到了与移动前相等的数字,我们就跳过这个指针位置,指针继续移动,直到遇到了不等于刚才数字的位置
代码演示
class Solution:
def threeSumClosest(self, nums,target):
n = len(nums)
if (not nums or n < 3):
return None
nums.sort()
res = float("inf")
for i in range(n - 2):
if (i > 0 and nums[i] == nums[i - 1]):
continue
L = i + 1
R = n - 1
while (L < R):
cur_sum = nums[i] + nums[L] + nums[R]
if (cur_sum == target):
return target
if (abs(cur_sum - target) < abs(res - target)):
res = cur_sum
if (cur_sum - target < 0):
L += 1
else:
R -= 1
return res
总结
多指针算法是一种典型的解决查找问题的方法,通常指针数大于2的话就不容易计算,所以我们会固定一个指针去移动另外两个,这就需要嵌套循环。
多指针法不仅多应用数组,更应用于链表,树和各种排序算法,所以大家一定要好好掌握,和三数之和,一起参照学习