码迷,mamicode.com
首页 > 其他好文 > 详细

hihocoder(1032) 最长回文子串

时间:2015-04-11 10:12:55      阅读:117      评论:0      收藏:0      [点我收藏+]

标签:

经典题,没什么好说的,直接上manacher,时间复杂度O(n),空间复杂度O(n),因为需要额外申请一个数组存储每个位置的子回文长度。

算法精髓:

1.把无论奇,偶长度字符串转换为奇数个。

2.利用已经得到的最长回文的右边界来减少重复计算的次数,如果右边界mx>i,则p[i] = min(mx-i, p[2*id-i]).

hihocoder的测试数据可能比较大,如果直接用C++的string拼接字符串直接就TLE了,很好奇为什么没有用右值引用优化,居然在构造阶段就超时了,

无奈只能换成字符数组。

Impl:

技术分享
 1 #include <string>
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 
 6 using namespace std;
 7 
 8 char* preProcess(char* str, char* tstr)
 9 {
10     int len = strlen(str);
11     int j = 0;
12     tstr[j++] = #;
13     for (int i = 0; i < len; ++i) {
14         tstr[j++] = str[i];
15         tstr[j++] = #;
16     }   
17     tstr[j++] = $;
18     tstr[j] = \0;
19     return tstr;
20 }
21 
22 
23 int manacher(char* str, char* str1)
24 {
25     char* tstr = preProcess(str, str1);
26     int len = strlen(tstr);
27     if (len == 2) return 0;
28 
29     int mx = 0, id; 
30     int* p = new int[len];
31     for (int i = 1; i < len-1; ++i)
32     {   
33         p[i] = i < mx ? min(mx-i, p[2*id-i]) : 0;
34 
35         while (tstr[i+p[i]+1] == tstr[i-p[i]-1]) 
36             p[i]++;
37 
38         if (p[i]+i > mx) 
39         {
40             id = i, mx = p[i]+i;
41         }
42     }
43 
44     int maxLen=1;
45     for (int i = 1; i < len-1; ++i)
46         maxLen = max(maxLen, p[i]);
47     delete [] p;
48     return maxLen;
49 }
50 
51 char str[1000010];
52 char tstr[2000020];
53 
54 int main()
55 {
56     int n;
57     scanf("%d", &n);
58 
59     while (n--)
60     {
61         scanf("%s", str);
62         printf("%d\n", manacher(str, tstr));
63     }
64 
65     return 0;
66 }
View Code

 

hihocoder(1032) 最长回文子串

标签:

原文地址:http://www.cnblogs.com/sheepsheep/p/4416446.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!