📜  门| GATE-CS-2017(Set 2)|问题27(1)

📅  最后修改于: 2023-12-03 14:58:31.836000             🧑  作者: Mango

问题27

题目: 现在给定一个字符串s,你需要找到最长的回文子串。回文串是正读和反读都相同的字符串。你需要返回字符串的最长回文子串。

输入格式:

  • 一个字符串s,长度不超过1000

输出格式:

  • 返回字符串的最长回文子串

示例:

输入:babad
输出:bab
解法

要找到最长的回文子串,可以使用动态规划的方法。

首先定义一个二维数组dp,其中dp[i][j]表示字符串s从下标i到下标j是否构成回文串。那么有以下三种情况:

  • 情况1: 当i = j,即一个字符时,肯定是回文串,即dp[i][j] = true。
  • 情况2: 当j = i + 1,即两个字符时,如果s[i] = s[j],则为回文串,即dp[i][j] = true。
  • 情况3: 当j > i + 1时,如果s[i] = s[j],并且dp[i+1][j-1]为真,则s[i]到s[j]为回文串,即dp[i][j] = true。

在遍历的过程中,记录最长回文子串的起始位置和长度,最后返回即可。

以下是对应的Python代码:

def longestPalindrome(s):
    n = len(s)
    max_len = 0
    start = 0

    # 初始化动态规划数组
    dp = [[False] * n for _ in range(n)]

    # 从字符串最后一个字符开始遍历
    for i in range(n - 1, -1, -1):
        # 单字符是回文串
        dp[i][i] = True
        # 计算长度为2的回文串
        if i < n - 1 and s[i] == s[i + 1]:
            dp[i][i + 1] = True

        for j in range(i + 2, n):
            # 判断i到j是否是回文串
            if s[i] == s[j] and dp[i + 1][j - 1]:
                dp[i][j] = True

        # 更新最长回文子串的起始位置和长度
        for j in range(i, n):
            if dp[i][j] and j - i + 1 > max_len:
                max_len = j - i + 1
                start = i

    # 返回最长回文子串
    return s[start:start + max_len]

你可以使用以下代码进行测试:

print(longestPalindrome("babad"))  # 输出 "bab"
print(longestPalindrome("cbbd"))  # 输出 "bb"
print(longestPalindrome("a"))  # 输出 "a"

以上是求解最长回文子串的动态规划算法。时间复杂度为O(n^2),空间复杂度为O(n^2)。