2020.05.21最长回文子串longestPalindrome
默认格式:
class Solution {
public String longestPalindrome(String s) {
}
}
解题思路:
之前做过验证回文字符串,最常的子串的各种问题,现在遇到这题简直就是对我这几天学习情况的一个考验,我今天势必要拿下这题。
首先,这种题目必定是时间复杂度O(n)能够解决的问题,然后我们要来找字符串的一些没有写出来的特点,总结这些特点就能帮助我们找到解题的办法。
1:首位相同,回文的首位必定是相同的,如果我们找到两个相同的字母,那么再确定中间夹杂的是否是回文。
2:回文的中心必定是AA或者ABA这样的形式,所以其实我们只需要判断每个字符和他前面的那一个或者是前面的第二个是否是相同的字符就能判断是否是回文的中心,在找到中心之后再向外扩展,这样就能找到最长的字符串了。
3:字符有他的ascii码,也许我们能够通过把字符的比较变成对数字的比较
4:需要有一种巧妙的方式来判断2中的情况
5:使用滑块,我只是听到过这个名字,不过感觉应该可以用在这个地方,想像一下,如果使用滑块要怎么实现,反正有非常重要的一点,不能往后退,也就是说,滑块的起点之前不存在回文的一部分。。。不可能的,回文没有到达结尾之前,不可能判断某一串字符串是否属于回文
总结上面说的几点,感觉2比较靠谱,所以现在开始实现
🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉
这是我第一次自己完成中等难度的题目并且超过50%的用户,证明这些天的训练是有用的,最起码思维能力提升了,懂得了如何解决算法的问题
算法部分非常好理解
public String longestPalindrome(String s){
int length=1;
int start=0;
if(s.length()==0)
return "";
if(s.length()>=2&&s.charAt(0)==s.charAt(1))
length=2;
for (int i=2;i<s.length();i++)
{
//如果当前字符和上一个字符一样
if (s.charAt(i)==s.charAt(i-1)){
//此时回文初始长度是2
int newlen=2;
for (int j=1;j<s.length()/2;j++){
//如果探测已经到达了数组边缘,跳出循环
if(i+j>=s.length()||i-1-j<0)
break;
//向两边扩展,判断是否是更大的回文,如果是,长度+2,如果不是,返回当前长度
if (s.charAt(i+j)==s.charAt(i-1-j)){
newlen+=2;
}
else
break;
}
if (newlen>length){
length=newlen;
start=i-length/2;
}
}
//如果当前字符和前面第二个字符一样
if(s.charAt(i)==s.charAt(i-2)){
//此时回文初始长度是3
int newlen=3;
for(int j=1;j<s.length()/2;j++){
//如果探测已经到达了数组边缘,跳出循环
if(i+j>=s.length()||i-2-j<0)
break;
//向两边扩展,判断是否是更大的回文,如果是,长度+2,如果不是,返回当前长度
if (s.charAt(i+j)==s.charAt(i-2-j)){
newlen+=2;
}
else
break;
}
if (newlen>length){
length=newlen;
start=i-length/2-1;
}
}
}
return s.substring(start, start+length);
}