1、最大回文子串
题目描述
对于一个字符串,请设计一个高效算法,计算其中最长回文子串的长度。
给定字符串A以及它的长度n,请返回最长回文子串的长度。
测试样例:
"abc1234321ab",12
返回:7
class Palindrome {
public:
string helper(string A,int n){
//j将字符串转换为首字符为$,其余用#隔开
string ret(2*n+2,'0');
ret[0]='$';
int i=1;
int j=0;
while(j<n){
ret[i++]='#';
ret[i++]=A[j++];
}
ret[i]='#';
return ret;
cout<<ret;
}
int getLongestPalindrome(string A, int n) {
string str=helper(A,A.size());
int len=str.size();
int mx=0;//前文记录的回文串最长影响到的地方,不一定是最长回文串
int id=0;//与mx对应的回文串的中心位置
int ret=0;
//p为从中间字符向两边扩展的长度
vector<int> p(len,1);
for(int i=1;i<len;i++){
if(i<=mx){
p[i]=min(p[2*id-i],mx-i);//若当前位置没有达到mx,则p[i]的初始值为2*id-i(i关于id的对称点的p值和mx-i中的较小值
}
//若大于mx,则没有办法进行初始化,保持为1,从中间向两边开始计数
while(str[i+p[i]]==str[i-p[i]]){
p[i]++;
}
//更新mx和id的值
if(i+p[i]>mx){
mx=i+p[i];
id=i;
}
//更新最长回文串的长度
if(ret<p[i]){
ret=p[i];
}
}
//最长回文串长度为新字符串中p的最大值-1
return ret-1;
}
};
2、最大回文子序列
和最大回文子串不同,子序列不要求连续。
class Solution {
public:
int longestPalindromeSequencer(string A) {
int n=A.size();
vector<vector<int>> dp(n,vector<int>(n,0));
for(int i=0;i<n;i++){
dp[i][i]=1;
}
for(int i=1;i<n;i++){
int tmp=0;
for(int j=0;j+i<n;j++){
if(A[j]==A[j+i]){
tmp=dp[j+1][j+i-1]+2;
}
else{
tmp=max(dp[j+1][j+i],dp[j][j+i-1]);
}
dp[j][j+i]=tmp;
}
}
return dp[0][n-1];
}
};