您的位置:首页 > 其它

Longest Palindromic Substring

2016-02-16 16:32 197 查看
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.

Manacher算法计算最长回文串

1. 字符串预处理

由于回文字符串存在奇偶两种情况

aba             abba

将两者情况统一处理将方便算法的执行,所以算法第一步便是将字符串统一,

2*length+1 可以将字符串统一变为奇数长度,字符串经过变化得到如下新的字符串。



2.用数组p来记录以各个字符为中心的回文串半径

Str:$  #  a  #  b  #  a  #  &

P :1  1  2  1  4  1  2  1  1

P的计算方法

以每个字符为中心,不断向外扩展,比较左右字符而得,但这种做法过于耗时。在Manacher算法中以非常精妙的方法进行了改进。对于p[i](以str[i]为中心的回文串半径)计算方式如下,首先大括号的范围表示以currentCenter为中心的回文串范围,j是i相对于currentCenter的索引,boundary为界限索引。

j=currentCenter-(i-currentCenter)=2*currentCenter-i;



2.1p[i]初始值计算分为两种情况:

(1)p[j]回文串依旧在p[currentCenter]范围内,则p[i]=p[j];



(2)p[j]回文串不在p[currentCenter]范围内,则p[i]=boundary-i;



2.2p[i]后续值扩展:

任意一个p[i]在初始值的基础上都可以继续递增,只要左右相等即可



3.最长回文串计算

只要通过遍历一遍p数组便可以得到最长回文串

代码如下:

class Solution {
public:
string longestPalindrome(string s) {
vector<char> str;
init(s,str);
vector<int> p;
pCalculate(p,str);
int beginIndex=0,endIndex=0, maxLength = 0;
for (int i=1;i<p.size();++i)
{
if (p[i]>maxLength)
{
maxLength = p[i];
if (maxLength>=2)
{
beginIndex = (i-p[i]+2)/2-1;
endIndex = (i+p[i]-2)/2-1;
}
}
}
return s.substr(beginIndex,endIndex-beginIndex+1);
}
void init(string s, vector<char>& str)
{
str.push_back('$');
str.push_back('#');
for (int i=0;i<s.size();++i)
{
str.push_back(s.at(i));
str.push_back('#');
}
str.push_back('&');
}
void pCalculate(vector<int>& p,vector<char>& str)
{
int boundary = 0;
int currentCenter = 0;
p.push_back(1);
for (int i=1;i<str.size()-1;++i)
{
if (boundary>i)
{
p.push_back(min(p[currentCenter*2-i],boundary-i));
}
else
{
p.push_back(1);
}
while (str[i-p[i]]==str[i+p[i]])
{
p[i]++;
}
if (p[i]+i>boundary)
{
boundary = p[i]+i;
currentCenter = i;
}
}
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: