题目:最长回文子串
给你一个字符串 s,找到 s 中最长的回文子串。
输入:一个字符串 s。你可以假设 s 的最大长度为 1000。
输出:s 中最长的回文子串。
示例:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
输入: “cbbd”
输出: “bb”
这道题笔者有两种解法,第一种是暴力求解,使用双重循环,对每个i、j对象构成的子串进行回文的判断,较为简单,但是时间复杂度较高,不是面试的最优解:
public static void main(String[] args) {
int maxLength = 0;
String res = "";
String str = "ABCCBERBA";
for(int i=0; i< str.length() - 1; i++){
for(int j= i+1; j< str.length() ; j++){
if(isValidHuiWen(str,i,j)){
if (j -i +1 > maxLength){
maxLength = j - i + 1;
res = str.substring(i,j+1);
}
}
}
}
System.out.println(res);
}
第二种应该使用动态规划,我们找到递推公式的过程比较绕,可以从短到长的去扩展这个字符串,判断dp[i][j]可以根据dp[i+1][j-1]进行递推,i 从后到前做减法,j从前到后做加法,这个过程中有几个情况:
- i和j相等,下标指向同一个字符,一定是回文 dp[i][j] = true
- i和j不等,差值为1,只要str.charAt(i)== str.charAt(j),就说明是回文,此时dp[i][j] = true
- i和j不等,差值大于1,那么在判断str.charAt(i)== str.charAt(j)的基础上,还需要dp[i+1] [j-1] = true,才能保证是回文
因此可以给出下述代码:
public class LongestHuiwenTestSelf {
public static void main(String[] args) {
String s = "cafqabbaqgwesgh";
String res = longestHuiwen(s);
System.out.println(res);
}
public static String longestHuiwen(String str) {
boolean[][] dp = new boolean[str.length()][str.length()];
if (str.length() == 1) {
return str;
}
String res = "";
for (int i = str.length() - 1; i > 0; i--) {
for (int j = i; j < str.length(); j++) {
if (i == j) {
dp[i][j] = true;
}
//如果j和i相等,或者
if (str.charAt(j) == str.charAt(i)) {
if(j - i ==0 || j-i ==1){
dp[i][j] = true;
} else if (dp[i + 1][j - 1]) {
dp[i][j] = true;
}
}
if (dp[i][j] && (j - i + 1) > res.length()) {
res = str.substring(i, j + 1);
}
}
}
return res;
}
}
经过测试,输出结果: qabbaq,说明是回文,判断成功