首页 > 代码库 > hiho 第1周 最长回文子串
hiho 第1周 最长回文子串
题目链接:http://hihocoder.com/problemset/problem/1032
#include <bits/stdc++.h>using namespace std;bool table[10000][10000] = {false};string longestPalindromeDP(string s){ int n = s.length(); int longestBegin = 0; int maxLen = 1; memset(table,0,sizeof(table)); for (int i = 0; i < n; i++) table[i][i] = true; //前期的初始化 for (int len = 2; len <= n; len++) { for (int i = 0; i < n-len+1; i++) { int j = i+len-1; if (s[i] == s[j] && table[i+1][j-1]) { table[i][j] = true; longestBegin = i; maxLen = len; } } } return s.substr(longestBegin, maxLen);}int main(){ int t; cin>>t; while(t--) { string str; cin>>str; string ans = longestPalindromeDP(str); cout<<ans.length()<<endl; } return 0;}
#include <bits/stdc++.h>using namespace std;const int maxn = 1000008;char instr[maxn],str[maxn*2];int rad[maxn*2];int Manacher(){ int i,j,maxx; int n = strlen(instr); memset(str,‘#‘,sizeof(str)); for(i=0;i<n;i++) str[(i+1)<<1] = instr[i]; n = (n+1)<<1; str[n] = ‘$‘; int maxRad; maxRad = j = maxx = 0; for(i = 0;i<n;i++) { if(i<maxx) rad[i] = min(rad[2*j-i],maxx-i); else rad[i] = 1; while(str[i-rad[i]]==str[i+rad[i]]) rad[i] ++; if(maxRad<rad[i]) maxRad = rad[i]; if(rad[i]+i>maxx) { j = i; maxx = rad[i] + i; } } return maxRad;}int main(){ int t; scanf("%d",&t); while(t--) { scanf("%s",instr); printf("%d\n",Manacher()-1); } return 0;}
先是用DP写了一下,
DP方程,就是用一个二维数组标记table[i][j] 字符串i,到j是否构成回文串,然后枚举最大长度len,
要是两端相等,并且,可以扩展,那么longestBegin = i,maxlen = len;时间复杂度还是O(n^2),并且数组都开不了。
然后就是Manacher算法:
参考:http://www.cnblogs.com/lv-2012/archive/2012/11/15/2772268.html
先扩充为两倍的字符串,rad[i]表示新的字符串第I个位置可以向左向右匹配的最大距离。求出这个rad数组,有一个结论,rad - 1就是原串对应的位置能匹配的最大长度。
那么怎么求rad数组:
求rad[i] 的时候,如果知道rad 前面的值,还有前面有个位置 ID,能够扩充的最大距离是max,
那么rad = min(rad[2*id-i],max-i);
原因:
当 mx - i > P[j] 的时候,以S[j]为中心的回文子串包含在以S[id]为中心的回文子串中,由于 i 和 j 对称,
以S[i]为中心的回文子串必然包含在以S[id]为中心的回文子串中,所以必有 P[i] = P[j],见下图。
当 P[j] > mx - i 的时候,以S[j]为中心的回文子串不完全包含于以S[id]为中心的回文子串中,但是基于
对称性可知,下图中两个绿框所包围的部分是相同的,也就是说以S[i]为中心的回文子串,其向右至少会
扩张到mx的位置,也就是说 P[i] >= mx - i。至于mx之后的部分是否对称,就只能老老实实去匹配了。
hiho 第1周 最长回文子串