您的位置:首页 > 其它

LeetCode-Longest Palindromic Substring-最长回文子串-Manacher

2014-10-17 16:46 531 查看
https://oj.leetcode.com/problems/longest-palindromic-substring/

这道题O(n^2)的DP的解法会超时。大致思路就是从0-n计算子串的最大子串,并利用ispar[p][q]数组记录[p,q]是否是回文以避免每次判断子串是否是回文。

class Solution {
public:
int n,m;
string longestPalindrome(string s) {
n=s.length();
vector<vector<bool>> ispar(n+1,vector<bool>(n+1,false));
for(int i=0;i<n;i++) {ispar[i][i]=true;ispar[i][i+1]=true;}
int start=0;
int len=1;
for(int i=0;i<n;i++){
for(int j=i-1;j>=0;j--){
if(s[j]==s[i]) {
ispar[j][i]=ispar[j+1][i-1];
if(ispar[j][i] && i-j+1>len){
len=i-j+1;
start=j;
}
}
}
}
string res=s.substr(start,len);
return res;
}
};


搜了答案看到了O(n)Manacher算法,这个方法有两个技巧:

1,通过添加特殊字符避免判断偶数长度回文,将所有回文都转换为奇数长度。

2,利用以前判断过的最长回文与当前字符i为中心的回文的位置关系为当前回文排除掉一些较短的可能。

class Solution {
public:
int n,m;
string longestPalindrome(string s) {
n=s.length();
string ss;
for(int i=0;i<n;i++){
ss+="#";
ss+=s[i];
}
ss+="#";
m=ss.length();
vector <int> p(m,0);
int mx=0;
int id=0;
for(int i=1;i<m;i++){
if (mx>i) p[i]=min(p[2*id-i],mx-i);
for(int j=p[i]+1;i+j<m && i-j>=0;j++){
if (ss[i-j]==ss[i+j]) p[i]++;
else break;
}
if (i+p[i]>mx){
id=i;
mx=i+p[i];
}
}
int maxp=0;
for (int i=0;i<m;i++) {
if(p[i]>maxp) {
id=i;
maxp=p[i];
}
}
string res;
for(int i=id-maxp;i<=id+maxp;i++){
if(ss[i]!='#') res+=ss[i];
}
return res;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: