题意理解
给定一个字符串,找出最长回文子串。
问题分析
用动规,思路是从每个字符开始递推,每次字符长度+1,判断回文的时候和之前的子串掐头去尾后剩下的子串关联起来,形成状态转移方程。
其他
本题的变化在于,动规的起点是多个,逐步扩展。注意这个思路的学习。
链接
class Solution {
public:
string longestPalindrome(string s) {
int len = s.size();
if (len == 1) return s;
vector<vector<int> > dp(len, vector<int>(len));
//长度1默认回文
for (int i = 0; i < len; i++) {
dp[i][i] = 1;
}
//长度2相等回文
for (int i = 0; i < len-1; i++) {
if (s[i] == s[i+1]) {
dp[i][i+1] = 2;
}
}
//长度>3
for (int len_i = 3; len_i <= len; len_i ++) {
for (int j = 0; j < len; j++) {
//cout << s.substr(j, len_i) << endl;;
if (j + len_i > len) {
break;
}
if (s[j] != s[j + len_i - 1]) {
dp[j][j+len_i-1] = 0;
}
else if (dp[j+1][j+len_i-2] == 0) { //内串须为回文才行
dp[j][j+len_i-1] = 0;
}
else {
dp[j][j+len_i-1] = dp[j+1][j+len_i-2] + 2; //每次两个字符,增加2
}
}
}
int max_i = 0;
int max_j = 0;
int max_len = INT_MIN;
for (int i = 0; i < len; i++) {
for (int j = 0; j < len; j++) {
if (dp[i][j] > max_len) {
max_i = i;
max_j = j;
max_len = dp[i][j];
}
}
}
return s.substr(max_i, max_j-max_i+1);
}
};