您的位置:首页 > 其它

Manacher算法求最长回文字串

2016-12-07 21:57 197 查看
最长回文字串和最长回文子序列不是一回事,最短回文子序列可以通过逆置原字符串得到一个新的字符串,两个字符串求公共子序列就可以了。

Manager算法解决的问题是在线性时间内找到一个字符串的最长回文字串

1.首先是解决奇回文和偶回文的问题:通过在字符串首位以及每个字符之间添加一个统一的字符,将所有的字符串转化为奇回文问题,方便后面的统一处理。

2主要思想就是通过一个变量存储已经计算过的最大回文字串,优化后面的计算。

详细步骤见程序员代码面试指南
牛客网地址为最长回文字串牛客网

代码以及测试如下

#include<iostream>
#include<string>
#include<map>
#include<vector>
#include<algorithm>
#include<utility>
#include<queue>
#include<functional>
using namespace std;

class Palindrome {
void getManacherString(const string &a, string &b){
int j = 0;
for (int i = 1; i < b.size(); i=i+2){
b[i] = a[j++];
}
}
public:
int getLongestPalindrome(string A, int n) {
// write code here
//获取处理后的字符串
string manacherString(2 * n + 1, '#');
getManacherString(A, manacherString);
//最右侧即将到达的位置
int r = -1;
//此刻对应的中心
int index = -1;
//每个位置的最大半径
vector<int> posR(2 * n + 1, 1);
//整个字符串的最大半径
int maxR = -1;

for (int i = 0; i < manacherString.size(); ++i)
{
//判断i是否在r的范围内若不在则不能优化
posR[i] = r>i ? (min(posR[2 * index - i], r - i)) : 1;

//不断增加posR的半径
while (i+posR[i]<manacherString.size() && i-posR[i] >-1){
if (manacherString[i + posR[i]] == manacherString[i - posR[i]])
++posR[i];
else
break;
}
//更新最右位置以及中心
if (i + posR[i] > r)
{
r = posR[i]+i;
index = i;
}
if (posR[i] > maxR)
maxR = posR[i];
}
return maxR - 1;
}
};
int main()
{
string A = "1221";
Palindrome p;
cout<<p.getLongestPalindrome(A,A.size());
system("pause");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息