Manacher HDOJ 3068 最长回文

题目传送门

关于求解最长回文子串,有dp做法,也有同样n^2的但只用O(1)的空间,还有KMP,后缀数组??

 1 int main(void)    {
 2     while (scanf ("%s", str + 1) == 1)  {
 3         int len = strlen (str + 1);
 4         memset (dp, false, sizeof (dp));
 5         for (int i=1; i<=len; ++i)  dp[i][i] = true;
 6         for (int i=1; i<len; ++i)   {
 7             dp[i][i+1] = (str[i] == str[i+1]);
 8         }
 9         int ans = 1;
10         for (int i=3; i<=len; ++i)  {
11             for (int j=1; j+i-1<=len; ++j)  {
12                 if (dp[j+1][j+i-2] && str[j] == str[j+i-1]) {
13                     dp[j][j+i-1] = true;
14                     ans = max (ans, i);
15                 }
16             }
17         }
18         printf ("%d\n", ans);
19     }
20
21     return 0;
22 }

n^2

但是n^2的复杂度是过不了3068这题,下面用O(n)的算法解决

 1 /*
 2     题意:求最长回文串(不是最长回文子序列)
 3     Manasher:一个好理解,实现方便,O(n)时间复杂的很屌的算法。
 4         简单说一下原理:首先将原字符串每个相邻之间插入一个不可能在字符串出现的字符,这样可以解决奇偶问题
 5                         然后p[i]表示以i为回文中心,最长的回文长度(单边),然而在原字符串中ans = max p[i] - 1
 6                         我认为算法精髓在于求p[i]时充分利用了回文的性质,跳过了一些无用的扫描
 7     详细解释:中文版    英文版 8 */
 9 /************************************************
10 * Author        :Running_Time
11 * Created Time  :2015-8-7 19:27:46
12 * File Name     :Manacher.cpp
13  ************************************************/
14
15 #include <cstdio>
16 #include <algorithm>
17 #include <iostream>
18 #include <sstream>
19 #include <cstring>
20 #include <cmath>
21 #include <string>
22 #include <vector>
23 #include <queue>
24 #include <deque>
25 #include <stack>
26 #include <list>
27 #include <map>
28 #include <set>
29 #include <bitset>
30 #include <cstdlib>
31 #include <ctime>
32 using namespace std;
33
34 #define lson l, mid, rt << 1
35 #define rson mid + 1, r, rt << 1 | 1
36 typedef long long ll;
37 const int MAXN = 1e5 + 10000;
38 const int INF = 0x3f3f3f3f;
39 const int MOD = 1e9 + 7;
40 char s[MAXN], str[MAXN*2];
41 int p[MAXN*2];
42
43 int Manacher(void)  {
44     str[0] = ‘$‘;  str[1] = ‘#‘;
45     int len = strlen (s);
46     for (int i=0; i<len; ++i)   {
47         str[i*2+2] = s[i];  str[i*2+3] = ‘#‘;
48     }
49     len = len * 2 + 2;  str[len] = ‘\0‘;
50     int mx = 0, id = 0;
51     for (int i=1; i<len; ++i)   {
52         if (mx > i) p[i] = min (p[2*id-i], mx - i);
53         else    p[i] = 1;
54         while (str[i-p[i]] == str[i+p[i]])  p[i]++;
55         if (mx < p[i] + i)  {
56             mx = p[i] + i;  id = i;
57         }
58     }
59     int ret = 0;
60     for (int i=0; i<len; ++i)   {
61         ret = max (ret, p[i]);
62     }
63     return ret - 1;
64 }
65
66 int main(void)    {     //HDOJ 3068 最长回文
67     while (scanf ("%s", s) == 1)  {
68         printf ("%d\n", Manacher ());
69     }
70
71     return 0;
72 }
时间: 2024-10-13 11:45:47

Manacher HDOJ 3068 最长回文的相关文章

hdoj 3068 最长回文 【manacher算法】

题意... 用传统的方法来做的话,要超时(就是要进行奇偶判断). manacher算法,百度一下讲解好的有很多. 纪念粘代码: #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define M 110010 char a[M], b[M<<1]; int p[M<<1]; int main(){ while(~scanf("

hdu 3068 最长回文(manacher&amp;最长回文子串)

最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7317    Accepted Submission(s): 2500 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有多组

Manacher&#39;s algorithm: 最长回文子串算法

Manacher 算法是时间.空间复杂度都为 O(n) 的解决 Longest palindromic substring(最长回文子串)的算法.回文串是中心对称的串,比如 'abcba'.'abccba'.那么最长回文子串顾名思义,就是求一个序列中的子串中,最长的回文串.本文最后用 Python 实现算法,为了方便理解,文中出现的数学式也采用 py 的记法. 在 leetcode 上用时间复杂度 O(n**2).空间复杂度 O(1) 的算法做完这道题之后,搜了一下发现有 O(n) 的算法.可惜

HDU 3068 最长回文 (manacher算法)

最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9188    Accepted Submission(s): 3159 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有多组

HDU 3068(最长回文-manacher)[Template:manacher]

最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9660    Accepted Submission(s): 3353 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有多组

HDU - 3068 最长回文(manacher算法)

题意:给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 分析: manacher算法: 1.将字符串中每个字符的两边都插入一个特殊字符.(此操作的目的是,将字符串长度统一变成奇数,道理很容易想---奇数+偶数=奇数or偶数+奇数=奇数) eg:abba--->#a#b#b#a# 此外,为了便于处理边界,可在字符串开始处再加另外一个特殊字符. eg:#a#b#b#a#--->$#a#b#b#a# 2.数组 P[i] 来记录以字符S[i]为中心的最长回文子串向

HDU 3068 最长回文(初遇manacher)

这题可用拓展KMP分治法来做http://blog.sina.cn/dpool/blog/s/blog_677a3eb30100knj8.html 复杂度O(nlogn)这种方法好复杂而且代码很长,不易理解. 相比之下Manacher就简单多了,算法本身也很简单 这里个易懂的资料http://wenku.baidu.com/view/3031d2d3360cba1aa811da42.html 复杂度O(n) kuangbin的模版(有一处修改) /* * 求最长回文子串 */ const int

HDU 3068 最长回文(Manacher)

题目链接:[kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher 题意 给出一个只由小写英文字符a,b,c-y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 思路 用特殊字符插入到s串中每两个字符中间,实现每个回文串都是奇数,再用manacher算法进行求解. 代码 #include <iostream> #include <algorithm> #include <cstring

hdu 3068 最长回文串 o(n) Manacher 算法

最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 10596    Accepted Submission(s): 3759 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有多