最长回文子字符串问题
来源:互联网 发布:淘宝美工培训班学费 编辑:程序博客网 时间:2024/05/21 07:02
Longest Palindromic Substring最长回文子字符串问题
Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.
1.动态规划
提示:第i个字符结尾的最长回文字符串
java代码
public static String longestPalindrome(String s) { String maxsubstring=""; int lastlength=0; for(int i=0;i<s.length();i++){ char a=s.charAt(i); if(i-lastlength-1>=0){ if(a==s.charAt(i-lastlength-1)){ maxsubstring=lastlength+2>maxsubstring.length()?s.substring(i-lastlength-1,i+1):maxsubstring; lastlength+=2; }else{ for(int stt=i-lastlength;stt<=i;stt++){ if(isPalindromeString(s,stt,i)){ maxsubstring=i-stt+1>maxsubstring.length()?s.substring(stt,i+1):maxsubstring; lastlength=i-stt+1; break; } } } }else{ for(int j=0;j<=i;j++){ if(isPalindromeString(s,j,i)){ maxsubstring=i-j+1>maxsubstring.length()?s.substring(j,i+1):maxsubstring; lastlength=i-j+1; break; } } } } return maxsubstring;}public static boolean isPalindromeString(String s,int st,int e){ int n=(st+e)/2; int l=(st+e)%2; boolean re=true; while(re&&st<=n){ if(s.charAt(st)!=s.charAt(2*n+l-st)){ re=false; break; } st++; } return re;}
2.中心扩展法
回文字符串显然有个特征是沿着中心那个字符轴对称。比如aha沿着中间的h轴对称,a沿着中间的a轴对称。那么aa呢?沿着中间的空字符”轴对称。
for i=1 to s.length
expand(s,i,i);//以第i个字符扩展
expand(s,i,i+1);//第i个字符后的空字符扩展
3.Manacher算法
由于回文串的长度可奇可偶,比如”bob”是奇数形式的回文,”noon”就是偶数形式的回文,马拉车算法的第一步是预处理,做法是在每一个字符的左右都加上一个特殊字符,比如加上’#’,那么
bob –> #b#o#b#
noon –> #n#o#o#n#
这样做的好处是不论原字符串是奇数还是偶数个,处理之后得到的字符串的个数都是奇数个,这样就不用分情况讨论了,而可以一起搞定。接下来我们还需要和处理后的字符串t等长的数组p,其中p[i]表示以t[i]字符为中心的回文子串的半径,若p[i] = 1,则该回文子串就是t[i]本身,那么我们来看一个简单的例子:
# 1 # 2 # 2 # 1 # 2 # 2 #1 2 1 2 5 2 1 6 1 2 3 2 1
由于第一个和最后一个字符都是#号,且也需要搜索回文,为了防止越界,我们还需要在首尾再加上非#号字符,实际操作时我们只需给开头加上个非#号字符,结尾不用加的原因是字符串的结尾标识为’\0’,等于默认加过了。通过p数组我们就可以找到其最大值和其位置,就能确定最长回文子串了,那么下面我们就来看如何求p数组,需要新增两个辅助变量mx和id,其中id为最大回文子串中心的位置,mx表示其半径,这个算法的最核心的一行如下:
p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1;//以i字符为中心的最短半径
可以这么说,这行要是理解了,那么马拉车算法基本上就没啥问题了,那么这一行代码拆开来看就是
如果mx > i, 则 p[i] = min(p[2 * id - i], mx - i)
否则, p[i] = 1
当 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之后的部分是否对称,就只能老老实实去匹配了。
对于 mx <= i 的情况,无法对 P[i]做更多的假设,只能P[i] = 1,然后再去匹配了。
参见如下实现代码:
string Manacher(string s) {// Insert '#'string t = "$#";for (int i = 0; i < s.size(); ++i) { t += s[i]; t += "#";}// Process tvector<int> p(t.size(), 0);int mx = 0, id = 0, resLen = 0, resCenter = 0;for (int i = 1; i < t.size(); ++i) { p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1; while (t[i + p[i]] == t[i - p[i]]) ++p[i];//判断实际以i字符为中心的回文半径 if (mx < i + p[i]) { mx = i + p[i]; id = i; } if (resLen < p[i]) { resLen = p[i]; resCenter = i; }}return s.substr((resCenter - resLen) / 2, resLen - 1);
}
- 最长回文子字符串问题
- 最长字符串回文子串问题
- 字符串的最长回文子串问题
- 最长回文子字符串
- 最长回文子字符串
- 最长回文子字符串
- 最长对称字符串问题/最长回文子串问题
- 最长回文字符串问题
- 字符串:最长回文子串
- 【字符串】最长回文子串
- 字符串中最长的回文子串问题
- 最长公共子串、最长公共子序列、最长回文子串、模式匹配、最大子序列--字符串问题整理
- 最长公共子串、最长公共子序列、最长回文子串、模式匹配、最大子序列--字符串问题整理
- 最长回文子串问题
- 最长回文子串问题
- 最长回文子串问题
- 最长回文子串问题
- 最长回文子序列问题
- 开发板移植ar9271网卡驱动问题
- js 判断屏幕滑动到底部
- listview实现新浪微博
- Linux 网络编程——并发服务器的三种实现模型
- 更新升级eclipse软件
- 最长回文子字符串问题
- DX 中的坐标变换
- 几个iOS工程通用模块介绍
- linux命令(7)——mv命令
- 表单一
- 四大组件 方便随时查阅
- Java容器(List、Map、Set、Iterator)
- HDOJ-1247Hat’s Words(Trie)
- OpenCV入门 - 调整图片尺寸