错误解法(遇到很长的字符串时会超时):
class Solution {
private boolean isPalindrome(StringBuilder s){
int i = 0;
int j = s.length() - 1;
while(i <= j){
if(s.charAt(i) != s.charAt(j))
return false;
i++;
j--;
}
return true;
}
public String longestPalindrome(String s) {
//假设回文字符串的长度由大大小,自己指定一个尺度k,来判断是否存在长度为k的回文字符串
int k = s.length();
while(k >= 2){
StringBuilder sb = new StringBuilder(s.substring(0, 0 + k));
//System.out.println(k + " " + sb);//
if(isPalindrome(sb))
return sb.toString();
for(int i = k; i < s.length(); i++){//有了尺度k,就可以借用slide window的想法,这里i就从k到结尾,代表可以移动的距离
sb.deleteCharAt(0);
sb.append(s.charAt(i));
//System.out.println(k + " " + sb);//
if(isPalindrome(sb))
return sb.toString();
}
k--;
}
return s.length() != 0 ? s.charAt(0)+"" : "";//一定存在长度为1的,那么就返回第一次出现的
}
}解法一:
class Solution {
//既然要求出一个字符串中最长的回文子串,通过两次循环可以解决(因为两次循环就可以求出所有的子串,再依次判断即可,但是长度过大时会超时)
//那么用一次循环,根据回文字符串的特点,要么是abba的形式,要么是abcba的形式,即分奇偶,那么就根据回文字符串的生成
//遍历字符串s,对于每一个字符,判断其左右所能生成的最大长度的子串,这样就不用求出所有的子串了,只用求s.length()*2个子串,而且中途还可以撤出
//比起上面博客所写的超时的错误解法,设子串长度为k,从s.length开始判断,每次的长度k要判断n-k个子串(利用slide window),就容易超时
//s.length()*2 是因为分奇偶判断 abba 还是abcba
int start = 0;
int max = 0;
//计算字符串s中第i,j个位置的字符往左往右所能生成的最长的回文子串(子串就是连续的)的长度
private int maxIsPalindrom(String s, int i, int j){//i=j时就代表是奇数aba,j = i+1时就代表是偶数abba
/*while(i >= 0 && j < s.length()){
if(s.charAt(i) == s.charAt(j)){
i--;
j++;
}
else{
break;
}
}
return j - i + 1;*/
//如果只是求出最长回文子串的长度,用上面注释的就可以了,但是要求出具体的子串,就要记录位置
while(i >= 0 && j < s.length()){
if(s.charAt(i) == s.charAt(j)){
i--;
j++;
}
else{
break;
}
}
if(j - i - 1 > max){
max = j - i - 1;//因为条件不满足时i已经多减了1,j已经多加了1,所以这里是j - i - 1
start = i + 1;//因为条件不满足时i已经多减了1,所以这里是i+1
}
return max;
}
public String longestPalindrome(String s) {
if(s.length() < 2){//空串和只有一个字符的直接返回就好
return s;
}
for(int i = 0; i < s.length(); i++){
maxIsPalindrom(s, i, i);//aba
maxIsPalindrom(s, i, i + 1);//abba
}
return s.substring(start, start + max);
}
}
本文介绍了一种高效算法用于找出给定字符串中的最长回文子串。通过一次循环结合回文特性,避免了传统双层循环所带来的超时问题。算法区分奇偶情况,仅需遍历字符串长度两倍的次数即可找到最长回文子串。
601

被折叠的 条评论
为什么被折叠?



