Manacher算法
复杂度O(N)
Python代码:
# -*- coding: utf-8 -*-
# manacher算法,求出字符串中的最长回文半径,复杂度为O(N)
s = list('aaaaaassaaaaa')
print len(s)
s.insert(0, '$')
for i in range(1, 2 * len(s), 2):
s.insert(i, '#')
s.append('0')
print s
p = [1] * (len(s) - 1)
p[1], p[2] = 1, 2
print p
max_id = 2 # 记录当前半径达到最右端的下标
for i in range(3, len(p)):
if max_id + p[max_id] > i:
p[i] = min(p[2 * max_id - i], p[max_id] - (i - max_id))
else:
p[i] = 1
while s[i + p[i]] == s[i - p[i]]:
p[i] += 1
if i + p[i] >= max_id + p[max_id]: # 记录当前半径达到最右端的下标
max_id = i
print p
print len(p)
p = [t - 1 for t in p if t != 1]
max_radius = max(p)
print p
print len(p)
print max_radius
#include <iostream>
using namespace std;
const int LEN = 100;
static int current_len;
#define min(x, y) (x) < (y) ? (x) : (y)
char* change(char str[], int N) {
char *new_str = new char[2 * N + 3];
new_str[0] = '$';
new_str[1] = '#';
for (int i = 0; i < N; ++i) {
new_str[2 * i + 2] = str[i];
new_str[2 * i + 3] = '#';
}
new_str[2 * N + 2] = '\0';
current_len = 2 * N + 3;
return new_str;
}
void display(char str[]) {
cout << str << endl;
}
void display(int* p) {
int ans = 1;
for (int i = 2; i < current_len - 2; ++i) {
if (p[i] == 1) continue;
cout << p[i] - 1 << '\t';
if (ans < p[i] - 1) ans = p[i] - 1;
}
cout << endl;
cout << "max palindrome length = " << ans << endl;
}
void manacher(char str[], int* p) {
p[1] = 1;
p[2] = 2;
int max_id = 2;
for (int i = 3; i < current_len; ++i) {
if (str[i] == 0) break;
if (max_id + p[max_id] > i)
p[i] = min(p[2 * max_id - i], p[max_id] - (i - max_id));
else
p[i] = 1;
while (str[i + p[i]] == str[i - p[i]]) p[i] += 1;
if (max_id + p[max_id] <= i + p[i])
max_id = i;
}
display(p);
}
int main() {
static char str[100];
cin >> str;
display(str);
current_len = strlen(str);
cout << "sizeof(str) = " << current_len << endl;
char* new_str = change(str, current_len);
display(new_str);
int* p = new int[current_len];
manacher(new_str, p);
delete[] new_str;
delete[] p;
system("pause");
return 0;
}