[hihocoder1032]最长回文子串
2016-11-30 22:21
323 查看
这里只是对于“最长回文子串”算法的简单定义与实现代码,具体请参照hihocoder的官网。
1.
从最长长度递减,检查所有的子串判断是否是回文子串,最差时间复杂度是O(n^2)。
2.
以字符串中心的较短子串非回文,则较长子串必定非回文。
3.
现在要求的是中心index=i的最长回文子串,如果index=j的最长回文子串长度maxPal[j]的右边界大于i(即maxPal[j]/2+j>i),那么可以知道对于任意2*i-maxPal[j]/2-j < k < maxPal[j]/2+j-i,有str[i+k] == str[2*j-i+k]。所以可以利用2*j-i处的最大回文子串的长度,得到当前处的回文子串长度的最小值。具体公式为maxPal[i]/2
>= min{j+maxPal[j]/2-i,maxPal[2*j-i]/2}。
此处不需要枚举所有的j以取得最大值,只需要计算j+maxPal[j]最大的j即可。
4.
上诉方法只能处理长度为奇数的回文子串,通过拓展原串(即在字符前后都插入特殊字符),可以把算法拓展到偶数长度的回文子串。
这样得到的回文子串的长度需要去除特殊字符的部分。首先明确的是拓展后的字符串的最长回文子串首尾都是特殊字符,否则可以在两端加入特殊字符使得长度+2。这样就可以通过maxPal[i]/2的奇偶性反应i的奇偶性(/i对应的是否为特殊字符)。如果i对应的是特殊字符(即i为偶数,即maxPal[i]/2为偶数),则得到就是偶数的回文子串;反之依然。
问题描述
回文串的定义是正读与反读相同;子串的定义是任意连续字符串;求给定字符串的最长回文子串的长度。详情请参照hihocoder的官网,上面也有详细的算法介绍。实现思路
1.
最简单的方法
从最长长度递减,检查所有的子串判断是否是回文子串,最差时间复杂度是O(n^2)。2.
枚举字符串中心
以字符串中心的较短子串非回文,则较长子串必定非回文。3.
利用之前的信息得到回文子串的最短长度
现在要求的是中心index=i的最长回文子串,如果index=j的最长回文子串长度maxPal[j]的右边界大于i(即maxPal[j]/2+j>i),那么可以知道对于任意2*i-maxPal[j]/2-j < k < maxPal[j]/2+j-i,有str[i+k] == str[2*j-i+k]。所以可以利用2*j-i处的最大回文子串的长度,得到当前处的回文子串长度的最小值。具体公式为maxPal[i]/2>= min{j+maxPal[j]/2-i,maxPal[2*j-i]/2}。
此处不需要枚举所有的j以取得最大值,只需要计算j+maxPal[j]最大的j即可。
4.
奇偶串的处理
上诉方法只能处理长度为奇数的回文子串,通过拓展原串(即在字符前后都插入特殊字符),可以把算法拓展到偶数长度的回文子串。这样得到的回文子串的长度需要去除特殊字符的部分。首先明确的是拓展后的字符串的最长回文子串首尾都是特殊字符,否则可以在两端加入特殊字符使得长度+2。这样就可以通过maxPal[i]/2的奇偶性反应i的奇偶性(/i对应的是否为特殊字符)。如果i对应的是特殊字符(即i为偶数,即maxPal[i]/2为偶数),则得到就是偶数的回文子串;反之依然。
代码如下
int maxPalindrome(char *str,int *maxPal,char *tmp_str){ int len = strlen(str); //expand string for (int i = 0;i < len;++i) tmp_str[2*i+1] = str[i]; /** max_j表示j+maxPal[j]/2最大的j; result表示最长回文子串的长度(没有去特殊符号); pal是暂时使用的变量,最后等于maxPal[i]/2+1; tmp_start表示求得的当前位置的最短回文子串的长度; **/ int max_j = 0,result = 1,pal,tmp_start; len = len*2+1; maxPal[0] = 1; for (int i = 1;i < len;++i){ //求当前位置的最短回文子串长度 tmp_start = 0; if (max_j+maxPal[max_j]/2-i > 0) tmp_start = max_j+maxPal[max_j]/2-i; if (2*max_j-i >= 0 && tmp_start > maxPal[2*max_j-i]/2) tmp_start = maxPal[2*max_j-i]/2; //从当前位置逐渐增加子串长度,判断是否回文,最后得到pal=maxPal[i]/2+1; for (pal = tmp_start+1;i-pal > -1 && i+pal < len && tmp_str[i+pal] == tmp_str[i-pal];++pal); maxPal[i] = pal*2-1; if (maxPal[i] > result) result = maxPal[i]; if (i+pal-1 > max_j+maxPal[max_j]/2) max_j = i; } //result/2&1用于区分奇偶子串,第一部分求取除中心外的长度,第二部分用于判断中心是否为特殊符号,决定是否加1 return result/2/2*2+((result/2)&1); }
相关文章推荐
- hihoCoder 1032 : 最长回文子串
- hihocoder:1032 : 最长回文子串
- [HihoCoder]#1032 : 最长回文子串
- Hihocoder 1032 最长回文子串 Manacher && 亲测暴力可过
- hihoCoder - 1032 - 最长回文子串 (字符串~)
- hihocoder 1032 最长回文子串
- [hihoCoder 1032]最长回文子串[Manacher]
- hihocoder 1032, 最长回文子串, manacher算法
- hihoCoder 1032 最长回文子串
- hihocoder 1032 最长回文子串
- hihocoder 1032 : 最长回文子串(Manacher)
- hdu3068 hihocoder 1032 最长回文子串 马拉车算法
- hihoCoder 1032 最长回文子串 (manacher算法)
- hihocoder 1032 最长回文子串(Manachar算法)
- hihocoder-1032 最长回文子串(Manacher)
- hihoCoder 1032 最长回文子串(Manacher算法)
- hihoCoder 1032 最长回文子串
- hihoCoder-1032 - 最长回文子串(Manacher 马拉车)
- [hihoCoder] #1032 : 最长回文子串
- 最长回文子串LPS(Hihocoder1032)