最长回文子串 - hiho一下

最长回文子串的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;
}
点赞