给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例 2:
输入:s = “cbbd”
输出:“bb”
示例 3:
输入:s = “a”
输出:“a”
示例 4:
输入:s = “ac”
输出:“a”
说明:回文串是指正序和倒序读的结果一样
动态规划过程可参考:
动态规划推导过程
/**
* 最长回文子串(动态规划)
* 先建立一个数据dp数据,dp[i][j]表示字符串下标从i到j的子串是否为回文串
* (用布尔值表示),回文串即顺着读和倒着读是一样的
* 基于回文串长度len(1<= len <=s.length)可以根据此可以建立动态规划方程:
* (1) len == 1 dp[i][i] = true
* (2) len == 2
* if(s[i] = s[i+1]) --> dp[i][i+1] = true
* if(s[i] != s[i+1]) --> dp[i][i+1] = false
*
* (3) len>2
* if(s[i] != s[j]) --> dp[i][j] = false
* if(s[i] = s[j]) -->dp[i][j] = dp[i+1][j-1]
* 第一层循环:len从3开始递增到s.length
* 第二层循环:i从0开始递增到s.length-len
* @param s ddcdcd
* @return 最长回文子串
*/
public static String longestPalindrome(String s) {
String result = "";
boolean [][] dp = new boolean[s.length()][s.length()];
//(1) 第一种场景
for(int i = 0; i<s.length(); i++){
dp[i][i] = true;
result = s.substring(i,i+1);
}
//(2)第二种场景
for(int i = 0; i<s.length()-1; i++){
if(s.charAt(i) == s.charAt(i+1)){
dp[i][i+1] = true;
result = s.substring(i,i+2);
}
}
//(3)第三种场景
for(int len = 3; len<=s.length(); len++){
for(int i =0; i+len<=s.length(); i++){
if(s.charAt(i) == s.charAt(i+len-1))
dp[i][i+len-1] = dp[i+1][i+len-2];
if(dp[i][i+len-1])
result = s.substring(i,i+len);
}
}
return result;
}