Manacher算法练笔,O(n)求最长回文子串。
参考资料:http://blog.csdn.net/ggggiqnypgjg/article/details/6645824
http://www.felix021.com/blog/read.php?2040
后缀数组和拓展KMP也可以求,不过时间复杂度都是O(nlogn)。
1 #include <cstdio> 2 #include <cstring> 3 4 const int MAXN = 110010; 5 6 char s[MAXN]; 7 char str[ MAXN << 1 ]; 8 int p[ MAXN << 1 ]; 9 int newL, n; 10 11 int min( int a, int b ) 12 { 13 return a < b ? a : b; 14 } 15 16 int max( int a, int b ) 17 { 18 return a > b ? a : b; 19 } 20 21 void init() 22 { 23 int i; 24 str[0] = '?'; 25 str[1] = '#'; 26 newL = 2; 27 for ( i = 1; s[i]; ++i ) 28 { 29 str[ newL++ ] = s[i]; 30 str[ newL++ ] = '#'; 31 } 32 str[ newL ] = '\0'; 33 n = newL; 34 35 return; 36 } 37 38 void DP() 39 { 40 int maxID = 0, id; 41 for ( int i = 1; i < newL; ++i ) 42 { 43 if ( maxID > i ) p[i] = min( p[ (id << 1) - i ], p[id] + id - i ); 44 else p[i] = 1; 45 46 while ( str[ i + p[i] ] == str[ i - p[i] ] ) ++p[i]; 47 if ( p[i] + i > maxID ) 48 { 49 maxID = p[i] + i; 50 id = i; 51 } 52 } 53 return; 54 } 55 56 int main() 57 { 58 while ( ~scanf( "%s", &s[1] ) ) 59 { 60 init(); 61 DP(); 62 63 int maxL = 0; 64 for ( int i = 1; i < n; ++i ) 65 maxL = max( maxL, p[i] - 1 ); 66 printf( "%d\n", maxL ); 67 } 68 return 0; 69 }