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

该博客主要介绍了LeetCode第16题的解决方案,目标是找到数组中三个整数的和,使得它们的和最接近给定的目标值。博主首先给出了一个粗略的O(n^2)解法,然后详细阐述了一个优化的O(nlogn)解法,通过排序和双指针来减少时间复杂度,确保找到最接近目标值的三数之和。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

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 第 5 题 '长回文子串' 的 Python 解法 对于给定字符串 `s`,返回其中的长回文子串是一个经典算法问题。一种高效的解决方案是利用中心扩展方法来寻找可能的大长度回文。 #### 中心扩展法解析 该方法基于观察到的一个事实:一个回文串可以由中间向两端不断扩散而得。因此可以从每一个字符位置出发尝试构建尽可能大的回文序列[^1]。 具体来说: - 对于每个字符作为单个字符的中心点; - 或者两个相同相邻字符作为一个整体中心点; - 向两侧延伸直到遇到不匹配的情况为止; 记录下每次找到的有效回文串及其起始索引和结束索引,并更新全局最优解。 下面是具体的 Python 实现代码: ```python def longest_palindrome(s: str) -> str: if not s or len(s) == 0: return "" start, end = 0, 0 for i in range(len(s)): len1 = expand_around_center(s, i, i) len2 = expand_around_center(s, i, i + 1) max_len = max(len1, len2) if max_len > end - start: start = i - (max_len - 1) // 2 end = i + max_len // 2 return s[start:end + 1] def expand_around_center(s: str, left: int, right: int) -> int: L, R = left, right while L >= 0 and R < len(s) and s[L] == s[R]: L -= 1 R += 1 return R - L - 1 ``` 此函数通过遍历整个输入字符串并调用辅助函数 `expand_around_center()` 来计算以当前位置为中心能够形长回文串长度。终得到的结果即为所求的大回文子串。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值