题目描述
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例1
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例2
输入: "cbbd"
输出: "bb"
第一次解法(暴力解法,会超出时间限制):
为什么我的代码是对的却不给我通过?哦,原来是超出时间限制,那没事了。
class Solution {
public String longestPalindrome(String s) {
int max_len = 0;
String result_str = "";
if (s == null) {
return result_str;
}
if (s.length() == 1) {
return s;
}
for (int i = 0; i < s.length()-1; i++) {
for (int j = i+1; j < s.length()+1; j++) {
String tem_str =s.substring(i, j);
if (if_sub(tem_str)) {
if (tem_str.length() > max_len) {
max_len = tem_str.length();
result_str = tem_str;
}
}
}
if (max_len >= s.length() - i) {
return result_str;
}
}
return result_str;
}
public boolean if_sub(String sub_str) {
int len = sub_str.length();
for (int i = 0, j = len-1; i <= j; i++, j--) {
if (! (sub_str.charAt(i) == sub_str.charAt(j))) {
return false;
}
}
return true;
}
}
第二次解法(动态规划)
Java集合类Set
最后一直说我越界越界,我都想一拳把电脑屏幕砸穿了,你还越界局局长,越界都会越界歪来。一直弄一只弄,把我给弄烦了。
创建一个二维数组 dp[n][n],dp[i][j]表示字符串第i到j是否为回文, 所判断的字符串为一个字符时它肯定是回文,两个字符时仅需判断这两个字符相不相等即可,这两个操作都通过初始化完成。
class Solution {
public String longestPalindrome(String s) {
int n = s.length();
if (s.isEmpty() || s.length() == 1) { //
return s;
} else {
boolean[][] dp = new boolean[n][n];
int left = 0, right = 0;
for (int i = 0; i < n; i++) { //初始化一字母和二字母的回文
dp[i][i] = true;
if ((i+1)<n && s.charAt(i) == s.charAt(i+1)) {
left = i;
right = i+1;
dp[i][i+1] = true;
}
}
for (int i = n-3; i >= 0; i--) { //找到三字母及以上的回文
for (int j = i+2; j < n; j++) {
dp[i][j] = (dp[i+1][j-1]) && (s.charAt(i)==s.charAt(j)); //两端字符相等且内部是回文串时,dp[i][j]也是回文串
if (dp[i][j] && (j-i)>(right-left)) {
left = i;
right = j;
}
}
}
return s.substring(left,right+1);
}
}
}