LeetCode Longest Palindromic Substring Part Manacher ALGORITHM
来源:互联网 发布:知乎历史版本 编辑:程序博客网 时间:2024/05/13 02:46
class Solution {public: string preProcess(string s){//避免回文串的奇偶性讨论 string ans=""; if (s.size()==0) { return "^$"; } ans.append("^"); for (int i=0; i<s.size(); i++) { ans.append("#");; ans+=s[i]; } ans.append("#$"); return ans; } string longestPalindrome(string s) { string ans=""; if (s.size()==0||s.size()==1) { return s; } string T=preProcess(s); int n=T.length(); int *P=new int[n];//动态开辟数组; int C=0,R=0; int max=-1; int start=0;//记录最长回文串的开始位置。 for (int i=1; i<T.size()-1; i++) {//计算P[i] int i_mirrior=2*C-i;//求得i关于C点对称的点的坐标 P[i]=R>i?min(P[i_mirrior], R-i):0;//如果能被C为中心的回文串覆盖到的话,那么可以直接等于P[i_mirror] while (T[i-P[i]-1]==T[i+P[i]+1]) {//尝试向左右两边扩展i为中心的回文串 P[i]++; } if (i+P[i]>R) {//如果已经超过右边界,则更新C,R。 C=i; R=i+P[i]; } if (P[i]>max) { max=P[i]; start=i-P[i]; } } ans=s.substr((start-1)/2,max); return ans; }};
参考http://articles.leetcode.com/2011/11/longest-palindromic-substring-part-ii.html学习了一下Manacher算法来求解最长回文子串的问题。
manacher算法在O(n)时间内求解出最长回文子串。首先,我们要对字符串S进行预处理,目的是得到只存在奇数长度的回文子串的字符串,避免了回文串长度奇偶性的讨论。转化步骤是在S的每一个字符之间插入一个‘#’。
例如:S="abababa",T="#a#b#a#b#a#b#a#";
为了找到最长回文子串,我们以每个T[i]为中心,向两边扩展,使得T[i-d]...T[i+d]组成一个回文串。那么在T中的最长回文串长度为2d+1。仔细观察可以发现,在原字符串中的回文串长度正好是d;
例如:S="aba",T="#a#b#a#".在T中的最长回文串为"#a#b#a#",center 为b,i=3,d=3;T[3-3]...T[3+3]组成最长回文串,长度为7.正好对应原字符串中的最长回文串的长度为d,即3.
那么,如何求得T中的最长回文子串呢?
我们引入辅助数组P。P[i]表示以T[i]为中心的回文串向两边散开的长度,即上面说到的d。
例如:
(图片来自于http://articles.leetcode.com/2011/11/longest-palindromic-substring-part-ii.html)由数组P,我们能立马得到最长回文串为abaaba。
现在我们想像一下在回文串abaaba中有一条直线画在中间。可以观察到直线两边的严格对称性。现在我们考虑一种更为复杂的情况。
假设我们已经计算得到了部分数组P的值,如图所示,我们已经有了P[1]-P[12],现在欲求解P[13].其中图中的黑色实线表示以a为中心的最长回文串,两边的L,R黑色点线表示以a为中心的最长回文串的两个边界。i'表示i以c为中心对称的点,即9。我们怎么能快速得到P[13]呢?
如图所示,两条绿色的横线表示了以i'与i为中心的最长回文子串的覆盖范围,显然P[i']=1.由于i‘为中心的回文子串,完全包含以C为中心的回文串中,且完全在C左边,由于对称性,显然,以i'为中心的回文串与以i为中心的回文串是完全对称的。因此,P[i]=P[i']=1;类似的,我们可以观察到P[12]=P[10]=0,P[13]=P[9]=1,P[14]=P[8]=0;
那么,现在我们考虑一种更为复杂的情况:
图中,绿色实线部分表示以i为中心以及以i'为中心的回文串中关于C严格对称的部分。穿越过center的部分,即绿色虚线的部分,也是严格对称的。但是,我们要注意到左边红线部分,以i'为中心的回文串已经超过了C为中心的回文串的左边界(图中红色部分)。我们由对称性能够得到的结论仅仅是p[15]>=5(绿色实线部分).要求解P[15],我们只能继续比较P[21]==P[9]吗??因为并不相等,所以我们得到结论P[15]=5.
所以总结一下:
--------------------------------------------------
if(P[i']<=R-i)
P[i]=P[i']
else
由右边界开始向外一对一对比较咯。
------------------------分割线------------------------
那么问题又来了。C与R的值是怎么维护的呢?假如刚才15为中心的回文串一路跨越了右边界R。那么我们就将C改为15,R改为以15为中心的右边界。为什么?将R右移,我们在求解接下来的P[i]的时候,是不是i为中心的子串被覆盖的可能性变大了呢?
总结一下:
如果i为中心的回文串扩展超过了边界R,则更新Center 为i,右边界为新的回文串的右边界。
------------------------分割线------------------------
最后,假如我们得到了T中的最长子串。如何对应到原字符串呢?在实际的代码中,参考上述网址的代码,在预处理的过程中,在前后边界还插入了特殊字符来避免边界讨论,,即S=“aba”,T=“^#a#b#a#$”,我们最后得到的最长回文串为T.substr(start_index,maxlen*2+1);对应于S的substr是什么呢?仔细观察可以得出,每个T中的index对应于S的下标为(index-1)/2。而长度我们前面分析过了,就是P数组中存的值,这里就是maxlen,因而。为s.substr((start_index-1)/2,maxlen); 希望能对大家有所帮助。
- LeetCode Longest Palindromic Substring Part Manacher ALGORITHM
- Longest Palindromic Substring (Manacher Algorithm)
- LeetCode 5. Longest Palindromic Substring---Manacher's Algorithm
- 【Leetcode】Longest Palindromic Substring Part
- 【leetcode】5.Longest Palindromic Substring >>Manacher算法
- leetcode 5 Longest Palindromic Substring(manacher)
- Longest Palindromic Substring (Manacher)
- Longest Palindromic Substring(leetcode medium algorithm problem)
- Leetcode Algorithm 005. Longest Palindromic Substring
- Manacher's algorithm for finding longest palindromic substring
- leetcode Longest Palindromic Substring Part II
- Manacher算法 //Longest palindromic substring
- Leetcode 5. Longest Palindromic Substring 新补充Manacher算法
- LeetCode 5 Longest Palindromic Substring(Manacher算法)
- leetcode 5. Longest Palindromic Substring(回文和Manacher算法)
- LeetCode: Longest Palindromic Substring
- LeetCode Longest Palindromic Substring
- LeetCode: Longest Palindromic Substring
- sqlite3命令行下的常用命令
- ios中Json解析的四种方法
- 使用libjpeg显示JPEG图像在framebuffer 测试(八)
- IOS支付宝支付
- Chicken Soup 【阻碍你成长的最大敌人竟然是它-无意识】
- LeetCode Longest Palindromic Substring Part Manacher ALGORITHM
- Null导致闪退crash,解决方法
- mysql快速入门
- nullsafe
- mysql基础教程
- 【鸟哥的linux私房菜-学习笔记】Linux 的启动流程分析
- 音乐放松
- UG工程图自动标注工具 64位 版本无限制
- @RequestBody、@ResponseBody的使用方法(2)