给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
解第一版:
1、DP求解,定义出错,定义a[i][j] = k表示长度 i+2 的字符串 s[ j 到 k ]示回文
2、这种定义没有利用好DP的优势回避奇偶回文辨别
3、例:
/*
a b b a 和 a b a
[0]应该存什么?
*/
class Solution {
public String longestPalindrome(String s) {
if(s.length()<2)
return s;
int n= s.length();
int[][] a= new int[n][n];
for(int i=0; i<n-1; i++){
if(s.charAt(i) == s.charAt(i+1))
a[0][i]= i+1;
if(i!=0 && ( s.charAt(i-1) == s.charAt(i+1)) )
a[1][i-1] = i+1;
}
for(int i=2; i<n; i++){
for(int j =0; j<n-1; j++){
/*
a b b a 和 a b a
[0]应该存什么?
*/
if(a[i-2][j+1]!=0 && a[i-2][j+1]+1<n
&& s.charAt(j) == s.charAt(a[i-2][j+1]+1 ) )
a[i][j] = a[i-2][j+1]+1;
if(a[i-1][j+1]!=0 && a[i-1][j+1]+1<n
&& s.charAt(j) == s.charAt(a[i-1][j+1]+1 ) )
a[i][j] = a[i-1][j+1]+1 ;
}
}
for(int i=n-1; i>=0; i--){
for(int j=0; j<n ;j++){
System.out.print(a[i][j] + " ");
if(a[i][j]!=0)
return s.substring(j,a[i][j]+1);
}
System.out.println();
}
return ""+s.charAt(n-1);
}
}
解答第二版:
class Solution {
public String longestPalindrome(String s) {
int n= s.length();
if(n<2)
return s;
boolean[][] a= new boolean[n][n];
String ans = s.substring(n-1,n);
int maxLen = 1;
//这个双重循环卡了我很久,大脑没转过来
for(int j=1; j<n ; j++){
for(int i=0; i<j; i++){
/*
合并 aa 、aba两种情况
if( i<n-1 && s.charAt(i)== s.charAt(i+1))
if( i<n-2 && s.charAt(i) == s.charAt(i+2))
*/
if(s.charAt(i) == s.charAt(j) &&( j-i<=2 ||a[i+1][j-1]) ){
a[i][j] = true;
if((j-i+1)>maxLen){
maxLen = j-i+1;
ans = s.substring(i,j+1);
}
}
}
}
return ans;
}
}