思路:
我直接用dp了,其它的不那么通用。
设dp[i][j]表示s[i,j]是否为回文数,是则值为1,否则为0。那么有:
显然dp[i][j]可以由子序列和当前s[i],s[j]推断出来。
注意到i,j变化的方向为:
我们沿着45°对角线填充即可。如下图所示:
上代码,还是比较简单的。
class Solution {
public String longestPalindrome(String s) {
if(s == null || s.length() == 0) {
return "";
}
int sLen = s.length();
if(sLen == 1) return s;
if(sLen == 2) return s.charAt(0)==s.charAt(1) ? s:String.valueOf(s.charAt(0));
int[][] dp = new int[sLen][sLen];
int maxLen = 0;
int leftRes = 0;
int rightRes = 0;
char[] sArr = s.toCharArray();
// 赋初值
for(int i=0; i<sLen; i++) {
dp[i][i] = 1;
if(i != sLen-1) {
if(sArr[i]==sArr[i+1]) {
dp[i][i+1] = 1;
leftRes = i;
rightRes = i+1;
maxLen = 2;
}else {
dp[i][i+1] = 0;
}
}
}
int b = 2;
while(b < sLen) {
for(int i=0;i<sLen-b;i++) {
int j = i + b;
if(sArr[i] == sArr[j]) {
dp[i][j] = dp[i+1][j-1];
if(dp[i][j] == 1 && maxLen<(j-i+1) ) {
leftRes = i;
rightRes = j;
}
}else {
dp[i][j] = 0;
}
}
b++;
}
return s.substring(leftRes,rightRes+1);
}
}