今天开始正式进行LeetCode的刷题之旅,自己的编程算法能力都太差了,所以决定进行苦练,查到的代码和解法,优化以及个人的理解,就这样。
专栏——【LeetCode】
LeetCode题目分类总结
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。
注意:假定每组输入只存在唯一答案。
例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
题解1:
class Solution(object):
def threeSumClosest(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
minval = 100000
nums.sort()
for i in range(len(nums)):
left = i + 1
right = len(nums) - 1
while left < right:
val = nums[i] + nums[left] + nums[right]
if abs(val - target) < minval:
minval = abs(val - target)
result = val
if val == target:
return target
if val <= target:
left += 1
else:
right -= 1
return result
题解2:
我们想到的是双指针的解题方法,建立l
和r
两个指针,然后进行遍历nums
。
class Solution:
def threeSumClosest(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
result = list()
nums.sort()
for i,m in enumerate(nums[0:-2]):
l, r = i + 1, len(nums) - 1
if nums[l] + nums[l + 1] + m > target:
result.append(nums[l] + nums[l + 1] + m)
elif nums[r] + nums[r - 1] + m < target:
result.append(nums[r] + nums[r - 1] + m)
else:
while l < r:
result.append(nums[l] + nums[r] + m)
if nums[l] + nums[r] + m < target:
l += 1
elif nums[l] + nums[r] + m > target:
r -= 1
else:
return target
result.sort(key=lambda x:abs(x-target))
return result[0]
我们首先将nums
排序,然后遍历nums
中的每个元素m
。
排序极大地提高了效率。
我们判断nums
中最大的两个数加上m
后是不是小于target
,如果是的话,此时我们没有办法找比这三个更大的和了,我们就要建立一个result
数组,将它们的和加入。我们判断nums
中最小的两个数加上m
后是不是大于target
,如果是的话,此时我们没有办法找比这三个更小的和了,我们就要将它们的和加入到result
中。
通过排序之后的最小值和最大值判断是否存在和
target
相同的情况,如果不存在,就加入到result
,然后再进行选取。
上述这两步操作是剪枝操作。
然后对于其他的情况,我们再按照之前的思路处理即可,直接将和加入result
中,而没有对最小距离单独处理。最后我们只要取和target
最近的值即可(将此策略添加到sort
函数中)。
通过绝对值的大小对
result
进行排序,可以选取最小的即为最后的结果。
通过几次实验的结果可以看出最好可以48ms,超过99.8%的人。