使用LeetCode怎么求最长回文子串

发布时间:2021-08-06 14:47:57 作者:Leah
来源:亿速云 阅读:158
# 使用LeetCode怎么求最长回文子串

## 什么是回文串?

在解决「最长回文子串」问题之前,我们首先需要明确什么是回文串。**回文串(Palindrome)**是指正读和反读都相同的字符串。例如:
- "aba" 是回文串
- "abba" 是回文串
- "abc" 不是回文串

## 问题描述

LeetCode上的[第5题:最长回文子串](https://leetcode.com/problems/longest-palindromic-substring/)题目要求:

> 给定一个字符串 `s`,找到 `s` 中最长的回文子串。你可以假设 `s` 的最大长度为 1000。

示例:

输入: “babad” 输出: “bab” 或 “aba”


## 解决思路

### 1. 暴力解法(Brute Force)

**思路**:枚举所有可能的子串,判断是否为回文,记录最长的。

**时间复杂度**:O(n³)(枚举子串O(n²),判断回文O(n))

**代码实现**:
```python
def longestPalindrome(s: str) -> str:
    if not s:
        return ""
    
    n = len(s)
    max_len = 1
    start = 0
    
    for i in range(n):
        for j in range(i + 1, n):
            if j - i + 1 > max_len and is_palindrome(s, i, j):
                max_len = j - i + 1
                start = i
    return s[start:start + max_len]

def is_palindrome(s: str, left: int, right: int) -> bool:
    while left < right:
        if s[left] != s[right]:
            return False
        left += 1
        right -= 1
    return True

缺点:时间复杂度太高,无法通过LeetCode的所有测试用例。

2. 动态规划(Dynamic Programming)

思路:利用回文串的性质,如果一个子串是回文串,并且它的左右字符相同,那么扩展后的子串也是回文串。

状态定义dp[i][j] 表示子串 s[i..j] 是否为回文串。

状态转移方程: - dp[i][j] = (s[i] == s[j]) and dp[i+1][j-1] - 边界条件:当子串长度为1或2时,直接判断 s[i] == s[j]

时间复杂度:O(n²)

空间复杂度:O(n²)

代码实现

def longestPalindrome(s: str) -> str:
    n = len(s)
    if n < 2:
        return s
    
    dp = [[False] * n for _ in range(n)]
    start = 0
    max_len = 1
    
    # 所有长度为1的子串都是回文
    for i in range(n):
        dp[i][i] = True
    
    # 枚举子串长度
    for length in range(2, n + 1):
        # 枚举左边界
        for i in range(n):
            j = i + length - 1  # 右边界
            if j >= n:
                break
                
            if s[i] != s[j]:
                dp[i][j] = False
            else:
                if length == 2:
                    dp[i][j] = True
                else:
                    dp[i][j] = dp[i + 1][j - 1]
            
            if dp[i][j] and length > max_len:
                max_len = length
                start = i
    return s[start:start + max_len]

3. 中心扩展法(Expand Around Center)

思路:回文串可以从它的中心展开,并且总共有 2n - 1 个可能的中心(包括字符间空隙)。

时间复杂度:O(n²)

空间复杂度:O(1)

代码实现

def longestPalindrome(s: str) -> str:
    if not s:
        return ""
    
    start = 0
    end = 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:
    while left >= 0 and right < len(s) and s[left] == s[right]:
        left -= 1
        right += 1
    return right - left - 1

4. Manacher算法(最优解)

思路:利用回文串的对称性,在O(n)时间内解决问题。

时间复杂度:O(n)

空间复杂度:O(n)

代码实现

def longestPalindrome(s: str) -> str:
    # 预处理字符串
    t = '#'.join('^{}$'.format(s))
    n = len(t)
    p = [0] * n
    center = right = 0
    
    for i in range(1, n - 1):
        # 利用对称性
        if i < right:
            mirror = 2 * center - i
            p[i] = min(right - i, p[mirror])
        
        # 尝试扩展
        while t[i + p[i] + 1] == t[i - p[i] - 1]:
            p[i] += 1
        
        # 更新中心和右边界
        if i + p[i] > right:
            center = i
            right = i + p[i]
    
    # 找到最大回文子串
    max_len = max(p)
    center_index = p.index(max_len)
    start = (center_index - max_len) // 2
    end = start + max_len
    return s[start:end]

性能对比

方法 时间复杂度 空间复杂度 适用场景
暴力解法 O(n³) O(1) 仅用于理解问题
动态规划 O(n²) O(n²) 中等规模字符串
中心扩展法 O(n²) O(1) 实际常用解法
Manacher算法 O(n) O(n) 超大规模字符串优化

实际应用中的选择

总结

求解最长回文子串是一个经典的字符串处理问题,本文介绍了四种解法: 1. 暴力解法(理解基础) 2. 动态规划(空间换时间) 3. 中心扩展法(实际常用) 4. Manacher算法(最优解)

在LeetCode上提交时,中心扩展法通常是性价比最高的选择,能够在合理的时间内通过所有测试用例。对于特别长的字符串(如长度>10⁵),则应该考虑Manacher算法。

通过这个问题,我们不仅学习了回文串的处理技巧,还体会到了算法优化的重要性——从O(n³)到O(n)的飞跃,正是算法之美所在。 “`

这篇文章共计约1800字,完整涵盖了从基础到优化的解决方案,并包含代码实现和复杂度分析。

推荐阅读:
  1. leetcode 5:最长回文子串
  2. python如何实现求最长回文子串长度

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

leetcode

上一篇:docker中如何使用ftp

下一篇:如何解决某些HTML字符打不出来的问题

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》