0%

Manacher Algorihtm

To calculate the longest palindrome substring.

Algorihtm

  • preprocessing
    insert ‘#’ between adjacent characters in the string, e.g., babad $\rightarrow$ #b#a#b#a#d#.
    remark: after preprocessing, the length of the string after and the length of the palindrome substring is odd.
  • array P
    P[i]: The maximum extension length of the palindrome substring centered on the i-th character.
    For example: abbabb
    abbabb
  • calculate P with previous information.
    maxRight: the rightmost boundray.center: the center correpsonds to maxRight.
    • case 1: $i \ge {\rm maxRight}$
      extend at the i-th character to enlarge maxRight.
    • case 2: $i < {\rm maxRight}$
      find mirror which is symmetric with $i$ about center, i.e., ${\rm mirror} + i = 2\times {\rm center}$.
      • ${\rm P}[{\rm mirror}] < {\rm maxRight} - i$, which means that ${\rm P}[i] = {\rm P}[{\rm mirror}]$.
        manacher1
      • ${\rm P}[{\rm mirror}] = {\rm maxRight} - i$, which means that ${]rm P}[i]$ is at least ${\rm maxRight} - i$ and may be extended.
        manacher2
      • ${\rm P}[{\rm mirror}] < {\rm maxRight} - i$, which means ${\rm P}[i] = {\rm maxRight} - i$ and can not be extended.
        manacher3

In summary, ${\rm P}[i] = \min\{ {\rm maxRight} - i, {\rm P}[{\rm mirror}] \}$.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
string manacher(string str) {
string str_trans = "#";
for (char c : str) {
str_trans += c;
str_trans += '#';
}
int n = str_trans.length();
vector<int> p(n, 0);
int maxRight = 0, center = 0;
int maxLen = 1, start = 0;
for (int i = 0; i < n; ++ i) {
if (i < maxRight) {
int mirror = 2*center - i;
p[i] = min(maxRight - i, p[mirror]);
}
int left = i - (1 + p[i]), right = i + (1 + p[i]);
while (left >= 0 && right <= n && str_trans[left] == str_trans[right]) {
p[i] ++;
left --;
right ++;
}
if (i + p[i] > maxRight) {
maxRight = i + p[i];
center = i;
}
if (p[i] > maxLen) {
maxLen = p[i];
start = (i - maxLen)/2;
}
}
return str.substr(start, maxLen);
}
-------------The EndThanks for reading.-------------