2-7

leetcode 16. 最接近的三数之和

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

例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.

与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).

Python most votes answer:

class Solution(object):
    def threeSumClosest(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        nums.sort()
        result = nums[0] + nums[1] + nums[2]
        for i in range(len(nums) - 2):
            j, k = i+1, len(nums) - 1
            while j < k:
                sum = nums[i] + nums[j] + nums[k]
                if sum == target:
                    return sum
                
                if abs(sum - target) < abs(result - target):
                    result = sum
                
                if sum < target:
                    j += 1
                elif sum > target:
                    k -= 1
            
        return result

算法复杂度:\(O(n^2)\)

实现思路:

  • 先排序;
  • 然后用穷举的方法找出可能的三元组合,最坏情况下要穷举出所有可能的三元组合;
  • 因为题目限定正确答案只有一组,所以如果三元组合的和正好等于目标值,循环应立即退出;
  • 通过比较当前和上一次的三元和与目标值之差的一范数来更新result

A fast python solution:

class Solution(object):
    def threeSumClosest(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        nums.sort()
        length = len(nums)
        closest = []
        
        for i, num in enumerate(nums[0:-2]):
            l,r = i+1, length-1
						
            # different with others' solution
						
            if num+nums[r]+nums[r-1] < target:
                closest.append(num+nums[r]+nums[r-1])
            elif num+nums[l]+nums[l+1] > target:
                closest.append(num+nums[l]+nums[l+1])
            else:
                while l < r:
                    closest.append(num+nums[l]+nums[r])
                    if num+nums[l]+nums[r] < target:
                        l += 1
                    elif num+nums[l]+nums[r] > target:
                        r -= 1
                    else:
                        return target
                    
        closest.sort(key=lambda x:abs(x-target))
        return closest[0]

算法复杂度:\(O(n)\),整个for循环部分的算法复杂度实际上是\(O(d)\),在最坏情况下是\(O(n)\)

算法分析:

  • 整个算法实际上采用的是“夹挤准则”:for循环中的前两个判断分支能够确定三元数组所在的精确区间(事实上for循环一开始只会进入前两个分支),当for循环进入第三个分支时,就只会在精确区间中进行while循环。当while循环结束时,整个循环就结束了。
  • enumerate函数的用法:链接
  • 匿名函数lambda的用法:链接
  • sort函数的用法:链接
posted @ 2019-06-26 21:53  mingyu02  阅读(236)  评论(0编辑  收藏  举报