首先想到的是暴力解法,时间复杂度为O(n^3)。在力扣中Java会超时无法通过。
//放在两层循环中,max表示当前回文串的长度,不断更新max,计算出当前回文字符串的起始位置。
class Solution {
public String longestPalindrome(String s) {
int max = 1;
int len = s.length();
int start = 0;
for(int i=0;i<len;i++){
for(int j=i;j<len;j++){
if(isPalindrome(s,i,j) && j-i+1>max){
max = j-i+1;
start = i;
}
}
}
return s.substring(start,start+max);
}
//判断一个字符串是否是回文字符串
public boolean isPalindrome(String s,int l, int r){
while(l<r){
if(s.charAt(l)!=s.charAt(r)){
return false;
}
l++;
r--;
}
return true;
}
}
//如何改进上述程序,就是放在一层循环中呢?我们可以采用中心扩散法。时间复杂度为O(n^2)。
class Solution {
public String longestPalindrome(String s) {
int max = 1;
int len = s.length();
int start = 0;
for(int i = 0;i<len - 1;i++){
int Odd = expandAroundCentor(s,i,i); //偶数的扩散中心都是从i开始
int Even = expandAroundCentor(s,i,i+1); //奇数的扩散中心从i和i+1开始
int maxLen = Math.max(Odd,Even);
if(maxLen > max){
max = maxLen;
start = i-(maxLen-1)/2;
}
}
return s.substring(start,start + max);
}
public int expandAroundCentor(String s,int left,int right){
int l = left;
int r = right;
while(l>=0 && r<s.length()){
if(s.charAt(l) == s.charAt(r)){
l--; //左边指针向左走
r++; // 右边指针向右走
}else{
break;
}
}
return r-l-1; //因为循环结束后的回文子串不包含l和r,因此长度是r-l+1-2;
}
}
成功通过!