给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
执行用时 :608 ms, 在所有 Java 提交中击败了8.18% 的用户
内存消耗 :51.7 MB, 在所有 Java 提交中击败了19.54%的用户
思路
维护一个二维数组dp[i][j],存储从下标i到下标j的子串是否为回文数组,从而很明显,我们只需要计算i<j(字符串以位置i开始,以位置j结束)这一部分的结果即可。
如果位置i的字母和位置j的字母不相等的话,则dp[i][j] = false;
若是相等,我们掐头去尾继续判断以i+1开始, j-1结束的子串是否是回文子串(即dp[i][j] = dp[i+1][j-1]);在这个时候要注意i+1<j-1这个公式才成立,若是i+1>=j-1,直接令dp[i][j] = true(即>是位置i和j相邻又相等。而dp[i][i]= true本身就成立);
还需注意的是,dp[i][j] = dp[i+1][j-1] 从这个动态方程里可以看出,要想求dp[i][j]得先求出它左下方的元素,所以我们要按列遍历。
class Solution {
public String longestPalindrome(String s) {
if(s == null || s.equals(""))
return s;
int length = s.length();
//dp有用的数据部分是i<j
boolean[][] dp = new boolean[length][length];
int max = 1;
String maxres = s.substring(0,1);
for(int j=1; j<length; j++){
for(int i=0; i<j; i++){
if(s.charAt(i) != s.charAt(j)){
dp[i][j] =false;
}
else if(i+1 < j-1){
dp[i][j] = dp[i+1][j-1];
}
else
//"cbbd" "bb"
dp[i][j] = true;
if(dp[i][j] && j-i+1 > max){
//System.out.println(maxres);
maxres = s.substring(i,j+1);
max = j-i+1;
//System.out.println(maxres);
}
}
}
return maxres;
}
}