以下题为例:
5. 最长回文子串
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
一、DP,O(n^2)
dp[i][j]表示i到j是否为回文字符串
class Solution {
public:
string longestPalindrome(string s) {
int len = s.size();
if(s.size() == 0) return s;
string res = s.substr(0,1);
vector<vector<int>>dp(len+1, vector<int>(len+1));
for(int i = 0; i < len; i++){
dp[i][i]= 1;
}
for(int i = len-2; i >=0; i--){
for(int j = i+1; j < len; j++){
if(s[i] == s[j]){
if(j == i+1)dp[i][j] = 1;
else dp[i][j] = dp[i+1][j-1];
}
if(dp[i][j] && j-i+1 > res.size()){
res = s.substr(i,j-i+1);
}
}
}
return res;
}
};
二、Manacher
学习参考
最小回文半径求法可以参考上述博文。
class Solution {
public:
string manacher(string ori_s) {
string s = "#";
for (auto c : ori_s) {
s += c;
s += "#";
}
int N = s.size();
vector<int> radius(N, 0);
int C = 0;
int R = 0;
int max_c = 0;
int max_r = 0;
for (int i = 0; i < N; ++i) {
if (i <= R) radius[i] = min(R - i, radius[2 * C - i]);
while (radius[i] + 1 + i < N && i - radius[i] - 1>= 0 &&
s[radius[i] + 1 + i] == s[i - radius[i] - 1]) ++radius[i];
if (radius[i] + i > R) {
R = radius[i] + i;
C = i;
}
if (radius[i] > max_r) {
max_r = radius[i];
max_c = i;
}
}
string res;
for (int i = max_c - max_r; i <= max_c + max_r; ++i) {
if (s[i] != '#') res += s[i];
}
return res;
}
string longestPalindrome(string s) {
return manacher(s);
}
};