九度 1528:最长回文子串

题目描述:

回文串就是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。
回文子串,顾名思义,即字符串中满足回文性质的子串。
给出一个只由小写英文字符a,b,c...x,y,z组成的字符串,请输出其中最长的回文子串的长度。

 

思路

1. 使用枚举法判断, 时间复杂度会到 o(n^3)

2. 动规的记忆化搜索, 时间复杂度会降到 o(n^2)

3. leetcode 给出了一个算法, 将时间复杂度降低到 o(n)

 

代码

#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;

char ori[200010];
char ist[500020];
int dist[500020];

int main() {
    
    while(scanf("%s", ori) != EOF) {
        int len = strlen(ori);
        int cur = 0;
        
        ist[cur++] = '^';
        ist[cur++] = '#';
        for(int i = 0; i < len; i ++) {
            ist[cur++] = ori[i];
            ist[cur++] = '#';
        }
        ist[cur++] = '$';
        ist[cur] = '\0';
        
        int ct = 1, rx = 0; // center, range
        int len2 = strlen(ist);
        memset(dist, 0, len2*4+5);
    
        for(int i = 1; i < len2-1; i ++) {
            int mirror = 2*ct - i;
            dist[i] = rx > i? min(rx-i, dist[mirror]):0;

            while(i+dist[i]+1 < len2 && i-dist[i]-1 >= 0 && ist[i+dist[i]+1] == ist[i-dist[i]-1])
                dist[i] ++;

            if(i+dist[i] > rx) {
                ct = i;
                rx = i+dist[i];
            }
        }
        
        int rev = 0;
        for(int i = 1; i < len2-1; i ++) {
            rev = max(rev, dist[i]);
        }
        cout << rev << endl;
    }
    return 0;
}

 

posted @ 2014-03-04 20:30  SangS  阅读(392)  评论(0编辑  收藏  举报