POJ3974 求字符串的最长回文子串的长度
2012-11-21 15:31
218 查看
回文串:如果某个字符串从左往右看与从右往左看是一样的,则称该字符串为回文串。
最长回文子串:求解一个字符串,它是某个给定字符串的子串,并且是回文串。
本题要求对于给定的字符串,求出它的最长回文子串的长度。可以采用Manacher算法在O(n)时间内求解。
本题也可以使用后缀数组求解,但是使用后缀数组大概需要用10s左右的时间,而使用Manacher算法需要的时间不到300ms。
最长回文子串:求解一个字符串,它是某个给定字符串的子串,并且是回文串。
本题要求对于给定的字符串,求出它的最长回文子串的长度。可以采用Manacher算法在O(n)时间内求解。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 1000005; char str ; //原字符串 char s[N << 1]; //用'#'作为间隔填充之后的字符串 int p[N << 1]; //p[i]表示以第i个字符为中心的回文子串的长度加1 int len; int ans; //最长回文子串的长度 void Manacher() { int i; int mx; //mx表示当前回文子串扩展的最右端 int id; //id表示mx是由哪个回文子串扩展出来的 len = (strlen(str) + 1) << 1; for (i = 0; i < len; ++i) //构造填充字符串 { s[i] = '#'; p[i] = 0; } for (i = 0; str[i] != 0; ++i) s[(i + 1) << 1] = str[i]; s[(i + 1) << 1] = 0; mx = 0; ans = 0; for (i = 1; s[i] != 0; ++i) //求解p数组 { if (mx > i) p[i] = min(mx - i, p[(id << 1) - i]); else p[i] = 1; while (s[i - p[i]] == s[i + p[i]]) ++p[i]; if (i + p[i] > mx) { mx = i + p[i]; id = i; } if (p[i] - 1 > ans) ans = p[i] - 1; //更新最长回文子串的长度 } } int main() { int Case = 0; while (scanf("%s", str) != EOF) { if (strcmp(str, "END") == 0) break; Manacher(); printf("Case %d: %d\n", ++Case, ans); } return 0; }
本题也可以使用后缀数组求解,但是使用后缀数组大概需要用10s左右的时间,而使用Manacher算法需要的时间不到300ms。
相关文章推荐
- 回文串是指这个字符串无论从左读还是从右读,所读的顺序是一样的;简而言之,回文串是左右对称的。现在,对于一个给定的母串 abcdedcb求最长回文子串的长度
- JAVA:返回字符串中最长回文子串的长度
- 给定一个字符串,求它的最长回文子串的长度,并打印出最长回文子串
- C语言 求一个字符串中最长回文子串的长度
- 对于一个字符串,请设计一个高效算法,计算其中最长回文子串的长度。
- 面试题:最长回文子串(即求对称字符串的最大长度 )
- 对于一个字符串,请设计一个高效算法,计算其中最长回文子串的长度。
- 求一个字符串中最长回文子串的长度(承接上一个题目)
- 给定一个字符串s,找出s中最长的回文子串,你可以假设s的最大长度是1000。
- 求字符串中的最长回文子串的长度
- 最长对称字符串问题/最长回文子串问题
- 求字符串中的最长回文子串
- 找工作知识储备(2)---数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- Manacher算法求最长回文子串的长度
- 【算法题】查找字符串中无重复最长子串的长度
- O(n)时间求字符串的最长回文子串
- (最长回文字串)字符串中对称的子字符串的最大长度
- 最长回文子串_POJ3974_O(n)完美求解--------入门级理解
- 求字符串的最长回文子串(manacher算法O(n)时间)
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串