返回
利用动态规划查找最长回文子串:LeetCode 5 号问题详解
前端
2023-10-17 02:04:18
**导言**
在字符串处理问题中,查找回文子串是一个常见的挑战。回文子串是指正向和反向读起来都相同的子串。在 LeetCode 5 号问题中,我们被要求找出给定字符串中最长的回文子串。
**动态规划方法**
动态规划是一种自底向上的算法,它将问题分解成较小的子问题,并使用之前子问题的解决方案逐步构建最终答案。在本例中,我们可以定义一个二维布尔数组 `dp[i][j]`,其中 `i` 和 `j` 分别表示字符串 `s` 的起始和结束索引。`dp[i][j]` 为 `true` 表示子串 `s[i:j]` 是回文,否则为 `false`。
**算法步骤**
1. **初始化:** 设置对角线元素 `dp[i][i]` 为 `true`,因为单个字符总是回文。
2. **两字符子串:** 检查所有长度为 2 的子串 `s[i:i+1]`。如果 `s[i] == s[i+1]`,则 `dp[i][i+1]` 设置为 `true`。
3. **递推:** 对于所有长度大于 2 的子串,使用以下递推公式:
```
dp[i][j] = dp[i+1][j-1] && (s[i] == s[j])
```
如果子串 `s[i+1:j-1]` 是回文,并且字符 `s[i]` 等于 `s[j]`,则子串 `s[i:j]` 也是回文。
**代码示例**
```python
def longestPalindrome(s: str) -> str:
n = len(s)
dp = [[False] * n for _ in range(n)]
max_len = 1
start = 0
# 初始化对角线元素
for i in range(n):
dp[i][i] = True
# 检查长度为 2 的子串
for i in range(n-1):
if s[i] == s[i+1]:
dp[i][i+1] = True
if max_len < 2:
max_len = 2
start = i
# 递推求解
for k in range(3, n+1):
for i in range(n-k+1):
j = i + k - 1
if s[i] == s[j] and dp[i+1][j-1]:
dp[i][j] = True
if max_len < k:
max_len = k
start = i
return s[start:start+max_len]
示例用例
-
输入:
"babad"
-
输出:
"bab"
-
输入:
"cbbd"
-
输出:
"bb"
-
输入:
"a"
-
输出:
"a"
总结
利用动态规划算法,我们可以有效地解决 LeetCode 5 号问题,查找字符串中最长的回文子串。该算法具有时间复杂度为 O(n^2) 和空间复杂度为 O(n^2),其中 n 是字符串的长度。通过逐步构建回文子串的解决方案,该算法提供了清晰和高效的方法来解决此类问题。