对于一个字符串,请设计一个高效算法,计算其中最长回文子串的长度。
给定字符串A以及它的长度n,请返回最长回文子串的长度。
测试样例:
“abc1234321ab”,12
返回:7
java实现:
动态规划:
1.dp[i][j]表示,若i到j已经是回文串勒,那么dp[i][j]是回文串的长度,否则dp[i][j]为0;
2.初始时,dp[i][i]=1
3.递推公式:
len>2: 当a[i]==a[j]&&dp[i+1][j-1]!=0时,dp[i][j]=len,否则为0,i<j.这是一个从已知回文串往两边展开的过程。当len=2时,需要特殊处理,因为当len=2时,dp[i+1][j-1]会访问到dp矩阵的左下方,我们并没有对这个位置做初始化处理,因此不能直接用递推公式。
import java.util.*;
public class Palindrome {
public int getLongestPalindrome(String A, int n){
int[][] dp = new int[n][n];
int max=1;
for(int i=0; i<n; i++){
dp[i][i] = 1;
}
char[] a = A.toCharArray();
for(int len=2; len<=n; len++){ //len为步长
for(int i=0; i<=n-len; i++){
int j = i+len-1; //最大为n-1
if(len==2 && a[i]==a[j]){
dp[i][j] = len;
max = 2;
continue;
}
if(a[i]==a[j] && dp[i+1][j-1]!=0){
dp[i][j] = len;
max = len;
}
}
}
return max;0
}
}
python实现:
补充:
[x:y:z]切片索引,x是左端,y是右端,z是步长,在[x,y)区间从左到右每隔z取值,默认z为1可以省略z参数.
步长的负号就是反向,从右到左取值.
a=“python”,a[: : -1]=nohtyp
从头到尾扫描字符串,每增加一个新的字符,判断以这个字符结尾,且长度为maxLen+1或者maxLen+2的子串是否为回文,如果是,更新。
class Palindrome:
def getLongestPalindrome(self, A, n):
maxLen=1
if A==A[::-1]:return n
for i in range(n):
if i-maxLen>=1 and A[i-maxLen-1:i+1]==A[i-maxLen-1:i+1][::-1]:
maxLen+=2
continue
if i-maxLen>=0 and A[i-maxLen:i+1]==A[i-maxLen:i+1][::-1]:
maxLen+=1
return maxLen