一、思路
- 当前操作:计算长度为
len的子串A[i...j]是否为回文; - 子问题:已知更短的子串
A[i+1...j-1]是否为回文,推导A[i...j]是否为回文; - 下一个子问题:若
A[i] == A[j]且内部子串是回文,则当前子串是回文;否则不是。
二、状态转移方程
- 定义
dp[i][j]:子串A[i...j]是否为回文; - 初始化:
dp[i][i] = true(长度为 1 的子串是回文); - 状态转移:
- 若A[i] != A[j]:dp[i][j] = false;
- 若A[i] == A[j]:
- 若j - i + 1 == 2(长度为 2):dp[i][j] = true;
- 否则:dp[i][j] = dp[i+1][j-1]。
三、代码
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class Solution {
public:
int getLongestPalindrome(string A) {
int n = A.size();
if (n == 0) return 0;
vector<vector<bool>> dp(n, vector<bool>(n, false)); // 修正为bool类型
int maxLen = 1; // ***** 单个字符长度至少为1
// 初始化长度为1的子串
for (int i = 0; i < n; i++) {
dp[i][i] = true;
}
// 按子串长度从2到n遍历
for (int len = 2; len <= n; len++) {
for (int i = 0; i + len <= n; i++) {
int j = i + len - 1; // 子串结束位置
if (A[i] != A[j]) {
dp[i][j] = false;
} else {
// 长度为2时,直接判定为回文
if (len == 2) {
dp[i][j] = true;
} else {
dp[i][j] = dp[i+1][j-1];
}
}
// 更新最长回文子串长度
if (dp[i][j] && len > maxLen) {
maxLen = len;
}
}
}
return maxLen;
}
};