求解字符串的最长回文子串的Manacher’s Algorithm
来源:互联网 发布:jquery ui.min.js下载 编辑:程序博客网 时间:2024/06/11 21:27
Manacher’s Algorithm
用Manacher’s Algorithm求解字符串的最长回文子串:这种算法的好处是将处理的时间复杂度降低到了O(n),是一种线性方法;
算法分析:
假设字符串为:GDGFGHJKKJHGFSFFSJFHS;
在任意的两个字符的开头结尾都插入相同字符如:#;结果如下:#G#D#G#F#G#H#J#K#K#J#H#G#F#S#F#F#S#J#F#H#S#;
然后我们可以把全新的字符串的下标表示出来从0开始;
#G #D #G# F#G # H # J # K # K # J # H # G # F # S # F #F#S#J#F#H#S#
0 1 2 3 4 5 6 7 8 9 10 ……………..
最后以全新字符串的下标创建一个数组P[];P[n]的值为相对应字符串所对应回文值,比如:P[1]=1、P[2]=0、P[3]=3、P[4]=0;
我们就可以看出数组P中的最大值为最长回文子串的长度,且最大值对应的字符为全新字符串的最长回文串的中心;所以算法的最核心就是求解全新字符串对应的回文数组P[]。(全新字符串长度为n)
求解P[i]分析:如下图所示;
求P[i]: 已知P[i]之前的值,C为回文串的中心,R为以C为中心的回文串的最外沿,其回文半径为R-C;从L到R以C为对称中心,i的对称点为i’。
1、当P[i]<R-i时,P[i] = P[i’];
2、当P[i]>=R-i时,P[i] = R-i ;然后接着遍历R+1和其以i为对称中心的对称点,如果还是满足对称则P[i]加1,然后一直往下遍历直到找到i的最大回文半径即P[i],然后修改对称中心把C移到i处即C = i ;同时把R= P[i]+i;接下来求解P[i+1],然后一直求解到P[n-1];
这样就可以求出来全新字符串对应的回文数组的最大值,也就求出最长回文串的长度。同时也知道最大回文串的对称中心i。
C++ 代码如下:
class Solution {
public:
string longestPalindrome(string s) {
string l;
l = s;
int r=0,i,n,j=0,i_mirror=0,centre=0; //对称中心、镜像对称点、回文半径都是0;
for(i=0;i<=s.size();i++){
l.insert(l.begin()+2*i,1,'#'); //在每个字符的开头和结尾插入#;
}
l.insert(l.begin(),1,'$'); //在全新字符串开头插入$;
n = l.size();
int p[n] ;
for(i=0;i<n-1;i++){ //遍历全新字符串;
i_mirror = 2*centre-i; //镜像对称点与对称中心的关系
p[i] = (r>i) ?min(r-i,p[i_mirror]) : 0; //遍历是否超出当前回文串;
while(l[i+p[i]+1]==l[i-p[i]-1]){ //遍历P[i]+1和其以i为对称中心的镜像对称点;
p[i]++; //符合条件加一;
}
if(p[i]+i>r){ //符合条件交换对称中心和回文半径;
centre = i;
r = i + p[i];
}
}
int max = 0,centre_index = 0;
for(i = 1;i<n-1;i++){ //求回文数组的最大值和其对称中心;
if(p[i]>max){
max = p[i];
centre_index = i;
}
}
return s.substr((centre_index-max-1)/2,max);
}
};
代码细节:这里为了便于代码的编写对于全新字符串做一下修改,在字符串的最前面加了一个字符$。
- Manacher's Algorithm 求解字符串的最长回文串
- 求解字符串的最长回文子串的Manacher’s Algorithm
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串
- Manacher's ALGORITHM: O(n)时间求字符串的最长回文子串
- 异常控制流
- 安卓开发-Broadcast接受者+六种常见Broadcast接受者案例+进程的优先级
- 轻松告别OpenCV Manager
- 图解什么是编译程序?程序设计语言典型的处理过程(预处理、编译、汇编)
- Python的生成器表达式与生成器函数
- 求解字符串的最长回文子串的Manacher’s Algorithm
- c++经典题---巧用算法输出A组成的三角形
- sysu-17C02签到
- python
- Java代码的执行顺序
- Python第三方库安装时编码问题utf-8变gbk
- 167. Two Sum II
- js-es6-Symbol新增的数据类型
- 趣图:程序员专属菜单