讲解:有什么浅显易懂的Manacher Algorithm讲解? - windliang的回答 - 知乎
最长回文子串:
class Solution {
public:
string init(string &s) {
string str = "^";
for (char &c: s) {
str += "#";
str += c;
}
str += "#$";
printf("==%s\n",str.c_str());
return str;
}
string longestPalindrome(string s) {
if (s.size() == 0) {
return s;
}
string str = init(s);
vector<int> p(str.size(), 0);
int center = 0, right = 0;
int maxn = 0, pos = 0;
for (int i = 1; i < str.size() - 1; i++) {
int mirror = 2 * center - i;
if (right > i) {
p[i] = min(right - i, p[mirror]);
} else { // right == i
p[i] = 0;
}
while (str[i + 1 + p[i]] == str[i - 1 - p[i]]) {
++p[i];
}
if (i + p[i] > right) {
center = i;
right = i + p[i];
}
if (p[i] > maxn) {
maxn = p[i];
pos = (i - maxn) / 2;
}
}
return s.substr(pos, maxn);
}
};
求回文子串的数目
p[i] 为新字符串的回文半径,不包含当前字符,所以回文子串数目为 (p[i]+1)/2
class Solution {
public:
string init(string &s) {
string str = "^";
for (char &c: s) {
str += "#";
str += c;
}
str += "#$";
printf("==%s\n",str.c_str());
return str;
}
int countSubstrings(string s) {
if (s.size() == 0) {
return 0;
}
int cnt = 0;
string str = init(s);
vector<int> p(str.size(), 0);
int center = 0, right = 0;
int maxn = 0, pos = 0;
for (int i = 1; i < str.size() - 1; i++) {
int mirror = 2 * center - i;
if (right > i) {
p[i] = min(right - i, p[mirror]);
} else { // right == i
p[i] = 0;
}
while (str[i + 1 + p[i]] == str[i - 1 - p[i]]) {
++p[i];
}
if (i + p[i] > right) {
center = i;
right = i + p[i];
}
// if (p[i] > maxn) {
// maxn = p[i];
// pos = (i - maxn) / 2;
// }
cnt += (p[i]+1)/2;
}
return cnt;
}
};