给定一个包括 n 个整数的数组 nums
和 一个目标值 target
。找出 nums
中的三个整数,使得它们的和与 target
最接近。返回这三个数的和。假定每组输入只存在唯一答案。
例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
解题思路
这个问题和之前的问题Leetcode 15:三数之和(最详细解决方案!!!)类似。我们首先想到的是通过对撞指针的方法来解这个问题。我们先要对nums
排序,接着建立l
和r
两个指针,然后我们遍历nums
-4 -1 1 2
i l r
我们要将l=i+1
、r=len(nums)-1
这样初始化,因为我们希望在[l:r]
中进行寻找操作。计算sum=nums[i]+nums[l]+nums[r]
和target
的差是多少,并且我们要记录下来,最后取最小的差对应的sum
作为结果。当l<r
的时候,我们就要对窗口进行缩放操作。如果sum<target
的话,我们就要将l++
,以寻找更大的sum
;否则的话,我们将r--
,以寻找更小的sum
。当本次操作结束后,我们就要进入下一轮循环
-4 -1 1 2
i l r
同样进行相同的操作。
class Solution:
def threeSumClosest(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
nums.sort()
nums_len = len(nums)
best_sum, best_dist = 0, float('inf')
for i in range(nums_len - 2):
l, r, cur_dist, cur_sum = i+1, nums_len-1, float('inf'), 0
while l < r:
tmp_sum = nums[i] + nums[l] + nums[r]
if abs(target - tmp_sum) < cur_dist:
cur_dist, cur_sum = abs(target - tmp_sum), tmp_sum
if tmp_sum < target:
l += 1
elif tmp_sum > target:
r -= 1
else:
return target
if cur_dist < best_dist:
best_dist, best_sum = cur_dist, cur_sum
return best_sum
我们实际上可一对上面这个问题进行剪枝操作。
我们首先将nums
排序,然后遍历nums
中的每个元素num
。我们判断nums
中最大的两个数加上num
后是不是小于target
,如果是的话,此时我们没有办法找比这三个更小的和了,我们就要建立一个result
数组,将它们的和加入。我们判断nums
中最小的两个数加上num
后是不是大于target
,如果是的话,此时我们没有办法找比这三个更大的和了,我们就要将它们的和加入到result
中。上述这两步操作是剪枝操作。
然后对于其他的情况,我们再按照之前的思路处理即可,但是此时我们直接将和加入result
中,而没有对最小距离单独处理。最后我们只要取和target
最近的值即可(将此策略添加到sort函数中)。
class Solution:
def threeSumClosest(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
result = list()
nums.sort()
for i,num in enumerate(nums[0:-2]):
l, r = i + 1, len(nums) - 1
if nums[l] + nums[l + 1] + num > target:
result.append(nums[l] + nums[l + 1] + num)
elif nums[r] + nums[r - 1] + num < target:
result.append(nums[r] + nums[r - 1] + num)
else:
while l < r:
result.append(nums[l] + nums[r] + num)
if nums[l] + nums[r] + num < target:
l += 1
elif nums[l] + nums[r] + num > target:
r -= 1
else:
return target
result.sort(key=lambda x:abs(x-target))
return result[0]
我将该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!