回文的最大特点就是中心对称,根据这个特点,我们解决这个问题的中心思想就是检测每个位置的左右两侧是不是对称的,并且记录最长的对称字符数。
但是这种思路只适用与121这种模式,对于1221这种模式需要进行适当的处理。而我所知道的有两种方法。
一:修改字符串将字符串:向两个字符中间插入特定的字符如:‘.’。即121-->1.2.1 , 1221-->1.2.2.1。全部变成奇数字符串。
二:在扩散检测前先检测是否有相同字符。
第一种的代码如下:
class Solution {
public static String longestPalindrome(String s) {
if(s==null||s.length()<=1)return s;
//向传入的字符串添加固定字符‘.’
s = join(s.toCharArray(),'.');
char[] char_s = s.toCharArray();
String longest = char_s[0]+"";
for(int i = 1;i<char_s.length-1;i++){
int b = 0;
//向第i个字符的两侧检测相同字符
while(i-b>=0&&i+b<char_s.length&&char_s[i-b]==char_s[i+b]){
b++;
}
if (longest.length()<=((b-1)*2+1)) {
//排除'.1.'模式的影响
if(longest.length()==((b-1)*2+1)&&char_s[i-b+1]=='.')continue;
longest = s.substring(i-b+1,i+b);
}
}
//移除字符串中插入的固定字符
return longest.replaceAll("\\.","");
}
//向传入的字符串添加固定字符‘.’
public static String join(char[] chars, char c ){
StringBuffer sf = new StringBuffer();
for(int i = 0;i<chars.length;i++){
sf.append(chars[i]);
if(i!=chars.length-1)sf.append(c);
}
return sf.toString();
}
}
第二种方法:
class Solution {
public static String longestPalindrome(String s) {
if(s.length()<=1)return s;
char[] char_s = s.toCharArray();
int maxLength = 0;
int a = 0;
int b = 0;
for(int i = 0;i<char_s.length;i++){
int firstIndex = i;
int lastIndex = i;
while(lastIndex+1<char_s.length&&char_s[i]==char_s[lastIndex+1])lastIndex++;
while((firstIndex-1)>=0&&(lastIndex+1)<char_s.length&&char_s[(firstIndex-1)]==char_s[(lastIndex+1)]){
firstIndex--;
lastIndex++;
}
if(maxLength<=lastIndex-firstIndex){
maxLength =lastIndex-firstIndex;
a = firstIndex;
b = lastIndex;
}
}
return s.substring(a,b+1);
}
}
题目来源:leetcode