最长回文子串的O(n)算法,Manacher算法。该算法又经典又简单,是ACM的入门算法,给出链接,就不介绍了。核心点在于,利用已经计算的回文子串长度信息,计算当前位置最长回文子串的长度。
然而,这个问题也是面试中常见的问题,博主哪天有空再回来写个生动的算法说明好了。
代码如下,见名知意:
/** * * @authors zhenpeng.fang * @nickname dumpling * @date 2015-10-18 18:26:48 */
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cmath>
using namespace std;
#define mp make_pair
typedef long long int64;
const double eps = 1e-6;
const int64 INF64 = 10000000000000000LL;
const int MAX_LEN = 2000020;
int T;
int len_array[MAX_LEN];
char temp_str[MAX_LEN], str[MAX_LEN];
int init(const char * src, char * dst){
int cnt = 1;
*dst++ = '#';
while(*src){
*dst++ = *src++;
*dst++ = '#';
cnt += 2;
}
*dst = '\0';
return cnt;
}
int computeLengthOfPalindrome(const char * str, int * len_array, int nstr){
int max_visited_sp = 1, max_visited_len = 1, max_len = 1;
memset(len_array, 0, sizeof(int) * nstr);
len_array[1] = 1;
for(int i = 2; str[i]; ++i){
len_array[i] = min(len_array[2 * max_visited_sp - i], max_visited_sp + max_visited_len - i);
while(i + len_array[i] + 1 < nstr
&& i - len_array[i] - 1 >= 0
&& str[i + len_array[i] + 1] == str[i - len_array[i] - 1]){
++len_array[i];
}
if(max_visited_sp + max_visited_len <= len_array[i] + i){
max_visited_sp = i;
max_visited_len = len_array[i];
}
max_len = max(len_array[i], max_len);
}
return max_len;
}
int main(){
//freopen("a.in", "r", stdin);
scanf("%d%*c", &T);
while(T--){
scanf("%s", temp_str);
int n = init(temp_str, str);
printf("%d\n", computeLengthOfPalindrome(str, len_array, n));
}
return 0;
}