题目描述
对于一个字符串,请设计一个高效算法,计算其中最长回文子串的长度。
给定字符串A以及它的长度n,请返回最长回文子串的长度。
测试样例:
"abc1234321ab",12
返回:7
最大回文子序列可以采取:
将原先串A翻转得到串B 求解A与B的最大公共子序列长度即可
而最大回文子串不可以采取该方式
反例:
1234694321 该串最大回文子串长度为1 但是翻转之后最大公共子串长度为4
思路:
采取动态规划方式
dp[i][j]表示str[i...j]子串是否为回文串 true:false
首先解决单个字符(一定构成回文子串) 双个字符(判断是否相等)
然后递增的讨论子串长度len是否构成回文子串(起点为i 终点为i+len-1)
转移方程:
dp[i][j]=1 (当A[i]==A[j] 并且 dp[i+1][j+1]=1) 即内部为回文子串且首尾相等
dp[i][j]=0 其他情况
一旦构成回文子串 更新结果 res=len
(若最终结果需要给出明确的子串 那么增加一个记录开始位置i的变量)
bool dp[1000][1000]; //dp[i][j]表示str[i...j]子串是否为回文串
int getLongestPalindrome(string A, int n) {
if(n==0)
return 0;
// write code here
for(int i=0;i<n;i++)
for(int j=i;j<n;j++)
dp[i][j]=false; ///初始化
int res=1;
for(int i=0;i<n-1;i++)
{
dp[i][i]=true;//单个字符一定构成回文子串
if(A[i]==A[i+1])
{
dp[i][i+1]=true; //双个字符构成回文字串 一定是相等的情况
res=2;
}
}
for(int len=3;len<=n;len++) //依此递增讨论子串的长度
for(int i=0;i+len-1<n;i++) //子串的起点
{
int j=i+len-1;//终点
if(A[i]==A[j] && dp[i+1][j-1]) //起点和终点相同 那么是否构成回文串取决于内部(A[i+1....j-1])
{
dp[i][j]=1;
res=len;//同时更新最大回文子串长度
}
else
{
dp[i][j]=false;
}
}
return res;
}