给定一个字符串 s
,找到 s
中最长的回文子串。你可以假设 s
的最大长度为 1000。
示例 1:
输入: "babad" 输出: "bab" 注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd" 输出: "bb"
思路:
反转 S,使之变成 S′。找到 S 和 S′之间最长的公共子串,这也必然是最长的回文子串。
这似乎是可行的,让我们看看下面的一些例子。
例如:S=“caba” , S′=“abac”
S 以及 S′之间的最长公共子串为 “aba”,恰恰是答案。
让我们尝试一下这个例子:
S=“abacdfgdcaba” , S′=“abacdgfdcaba”
S 以及 S′ 之间的最长公共子串为 “abacd”,显然,这不是回文。
算法
我们可以看到,当 S的其他部分中存在非回文子串的反向副本时,最长公共子串法就会失败。为了纠正这一点,每当我们找到最长的公共子串的候选项时,都需要检查子串的索引是否与反向子串的原始索引相同。如果相同,那么我们尝试更新目前为止找到的最长回文子串;如果不是,我们就跳过这个候选项并继续寻找下一个候选。
这给我们提供了一个复杂度为 O(n^2)动态规划解法,它将占用 O(n^2)的空间。
JAVA:
class Solution {
public String longestPalindrome(String s) {
int len=s.length();
String str="";
String newstr1="",newstr2="";
int end=0,start=0;
int i,j;
if(len==1) return s;
if(len==0) return "";
for(i=len-1;i>=0;i--){ //将字符串反转
str+=s.charAt(i);
}
for(i=0;i<len;i++){
for(j=i;j<len;j++){
newstr2=str.substring(i, j+1);
//System.out.println(newstr2);
if(s.contains(newstr2)){
if(newstr2.length()>newstr1.length()){
start=s.indexOf(newstr2);
end=j;
if(start+end==len-1){
newstr1=newstr2;
}
}
}
}
}
return newstr1;
}
}
但是,提交时有个不幸的消息,代码没问题,但是超时了...