📜  门|门 IT 2008 |第 50 题(1)

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

门|门 IT 2008 |第 50 题

这是一道经典的编程题,出现在 2008 年的门|门 IT 期刊中,考察了程序员的算法和数据结构知识。本题目需要求解一个字符串中的最长回文子串,即在给定字符串中找到一个最长的子串,使得它从左往右读和从右往左读都是一样的。

解题思路

解决本题需要用到动态规划的思想。定义一个二维数组 $dp[i][j]$ 表示字符串从 $i$ 到 $j$ 是否是回文串。对于一个子串 $s_i\cdots s_j$,如果 $s_i=s_j$ 并且 $s_{i+1}\cdots s_{j-1}$ 是回文串,那么 $s_i\cdots s_j$ 也是回文串。

同时,还需要注意两个边界条件:

  1. 对于长度为 $1$ 或 $2$ 的子串,只需判断左右两个字符是否相等即可。
  2. 对于所有长度 $j-i+1\leq 2$ 的子串,一定是回文串。

在求解 $dp$ 数组时,需要依次枚举子串的长度 $len=1,\cdots,n$,以及子串的起始位置 $i=1,\cdots,n-len+1$。这样,就可以在 $O(n^2)$ 的时间复杂度内求出整个 $dp$ 数组。

最后,从 $dp$ 数组中所有值为真的位置中选取一个最长的子串即可。

代码实现(Python)
def longest_palindrome(s: str) -> str:
    n = len(s)
    dp = [[False] * n for _ in range(n)]
    ans = ""

    for l in range(n):
        for i in range(n - l):
            j = i + l
            if l == 0:
                dp[i][j] = True
            elif l == 1:
                dp[i][j] = (s[i] == s[j])
            else:
                dp[i][j] = (s[i] == s[j] and dp[i + 1][j - 1])
            
            if dp[i][j] and l + 1 > len(ans):
                ans = s[i:j+1]

    return ans

以上便是本题的解题思路和 Python 实现代码。