Leetcode 16:最接近的三数之和(最详细的解法!!!)

版权声明:本文为博主原创文章,未经博主允许不得转载。有事联系:[email protected] https://blog.csdn.net/qq_17550379/article/details/83029688

给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。

例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).

解题思路

这个问题和之前的问题Leetcode 15:三数之和(最详细解决方案!!!)类似。我们首先想到的是通过对撞指针的方法来解这个问题。我们先要对nums排序,接着建立lr两个指针,然后我们遍历nums

-4 -1  1  2
 i  l     r

我们要将l=i+1r=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

如有问题,希望大家指出!!!

猜你喜欢

转载自blog.csdn.net/qq_17550379/article/details/83029688