返回

如何找到最长回文子串

闲谈

揭秘回文子串的奥秘:使用动态规划轻松寻觅

什么是回文子串?

回文子串是一种神奇的字符串,正着读和倒着读都完全一样。就像单词 "racecar",无论从哪个方向读,都是一样的。

寻找回文子串的方法

要找到给定字符串中最长的回文子串,我们可以借助一种叫做动态规划的技术。它就像一个超级侦探,将大问题分解成一系列小问题,然后逐个解决,最终揭开谜底。

动态规划的精髓

我们使用一个二维表格来存储我们解决小问题的答案。对于字符串中的每个子串,表格中的一个单元格记录了这个子串中最长的回文子串的长度。

算法步骤

  1. 初始化: 首先,我们初始化表格,每个子串自己本身就是一个长度为 1 的回文子串。
  2. 递推: 然后,我们从左上角开始,依次填满表格。对于每个子串,我们检查它的首尾字符是否相同。如果相同,我们利用前面子串的解,再加上 2,得到这个子串最长回文子串的长度。否则,我们比较这个子串去掉首尾字符后的最长回文子串长度。
  3. 求解: 我们不断填充表格,直到填满整个表格。表格右下角的单元格就包含了整个字符串中最长回文子串的长度。

代码示例

def longest_palindrome(string):
    """找到给定字符串中最长的回文子串"""
    n = len(string)
    dp = [[False] * n for _ in range(n)]

    # 初始化:每个字符都是长度为 1 的回文子串
    for i in range(n):
        dp[i][i] = True

    max_len = 1
    start = 0

    # 递推:从右下角开始填表格
    for i in range(n - 1, -1, -1):
        for j in range(i + 1, n):
            if string[i] == string[j]:
                # 如果首尾字符相同,利用前面子串的解
                if j - i == 1 or dp[i + 1][j - 1]:
                    dp[i][j] = True
                    if j - i + 1 > max_len:
                        max_len = j - i + 1
                        start = i

    return string[start:start + max_len]


# 测试一下
s = "babad"
print(longest_palindrome(s))  # 输出:"bab"

结论

动态规划是一种强大的技术,可以帮助我们解决看似复杂的字符串问题。通过将大问题分解成小问题,我们可以一步一步地找到最优解。回文子串的寻觅就是这样一个例子,它向我们展示了动态规划的强大功能。

常见问题解答

1. 什么样的字符串可以称为回文串?
答:正着读和倒着读都完全一样的字符串称为回文串。

2. 动态规划的优点是什么?
答:动态规划可以将大问题分解成一系列小问题,然后逐步求解,最终得到问题的整体解决方案。

3. 如何初始化动态规划表格?
答:对于回文子串问题,我们初始化表格,每个子串自己本身就是一个长度为 1 的回文子串。

4. 如何递推填充动态规划表格?
答:我们从左上角开始,依次填满表格。对于每个子串,我们检查它的首尾字符是否相同。如果相同,我们利用前面子串的解,再加上 2,得到这个子串最长回文子串的长度。否则,我们比较这个子串去掉首尾字符后的最长回文子串长度。

5. 如何得到最长回文子串?
答:动态规划表格右下角的单元格包含了整个字符串中最长回文子串的长度。