[LeetCode] 16.最接近的三数之和 最优解@Python

题目

Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

Example:
Given array nums = [-1, 2, 1, -4], and target = 1.
The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).

粗略解法

  • 参考三数之和可以首先得到一个粗略解法
  • 同样是先对nums排序,只不过:
    • 处理的是和为target而非0的三数和问题
    • 对于每次相加得到的total,需要进行一个最接近判断
class Solution(object):
    def threeSumClosest(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        nums.sort()
        closest = nums[0]+nums[1]+nums[2]
        
        for i in range(len(nums)-2):
            left, right = i+1, len(nums)-1
            
            while left < right:
                total = nums[i] + nums[left] + nums[right]
                
                if total == target:
                    return target
                
                if abs(total-target) < abs(closest-target):
                    closest = total
                    
                if total < target:
                    left += 1
                elif total > target:
                    right -= 1
        
        return closest

最优解法

  • 之前的粗略解法复杂度是 O ( n 2 ) O(n^2) O(n2),还可以做进一步的优化(14-24行):
    1. nums[i]+nums[left]+nums[left+1]为当前及之后时刻所有和中最小值(nums经过排序是按大小升序的),如果这个加和大于target,那么意味着之后所有时刻的加和都会更加大于target,因此只需比较closest、target、当前加和的值,并break即可(14-18行)
    2. nums[i]+nums[right]+nums[right-1]为该循环所有加和中最大值,若这个值仍小于target,那么意味当前循环所有加和更加小于target,因此只需比较closest、target、当前加和的值,并进入下一个循环即可(20-24行)
    3. 剩余部分与之前的解法相同(26-36行)
class Solution(object):
    def threeSumClosest(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        nums.sort()
        closest = nums[0]+nums[1]+nums[2]
        
        for i in range(len(nums)-2):
            left, right = i+1, len(nums)-1
            
            min_value = nums[i] + nums[left] + nums[left + 1]
            if min_value > target:
                if abs(min_value-target) < abs(closest-target):
                    closest = min_value
                break
            
            max_value = nums[i] + nums[right] + nums[right - 1]
            if max_value < target:
                if abs(max_value-target) < abs(closest-target):
                    closest = max_value
                continue
            
            while left < right:
                total = nums[i] + nums[left] + nums[right]
                if total == target:
                    return target
                if abs(total-target) < abs(closest-target):
                    closest = total
                if total < target:
                    left += 1
                elif total > target:
                    right -= 1
        return closest

[LeetCode] 16.最接近的三数之和 最优解@Python_第1张图片

你可能感兴趣的:(刷题)