给你一个字符串 s
,找到 s
中最长的回文子串。
解析:
1.暴力解法:双指针,遍历所有的回文子串,找到最长的。但超出了时间限制。
java:
class Solution {
public String longestPalindrome(String s) {
if(s.length()==0||s==" ") return "";
int max=0,start=0,end=0;
String sub=" ";
for(int i=0;i<s.length();i++){
for(int j=i+1;j<s.length();j++){
sub=s.substring(i,j+1);
if(isPalindrome(s,i,j)&&sub.length()>max){
max=sub.length();
start=i;
end=j;
}
}
}
return s.substring(start,end+1); //注意此方法是左闭右开
}
public boolean isPalindrome(String s,int m,int n){
while(m<n){
if(s.charAt(m)!=s.charAt(n)){
return false;
}
m++;n--;
}
return true;
}
}
二、中心扩散法
以串中每个(每两个)字母为中心,向左向右扩展到最大,最终找到最长的。
java:
class Solution {
public String longestPalindrome(String s) {
if(s.length()==0||s==" ") return "";
int start=0,end=0;
//中心扩展
for(int i=0;i<s.length();i++){
int len1=subString(s,i,i);//奇数,以一个扩展
int len2=subString(s,i,i+1);//偶数,以两个扩展
int len=Math.max(len1,len2);
if(len>(end-start+1)&&len==len1){//这里我把两个情况分开计算了,没有理解答案的合并计算
start=i-(len-1)/2;
end=i+(len-1)/2;
}
else if(len>(end-start+1)&&len==len2){
start=i-len/2+1;
end=i+len/2;
}
}
return s.substring(start,end+1);//注意这里是左闭右开
}
public int subString(String s,int m,int n){
while(m>=0&&n<s.length()&&s.charAt(m)==s.charAt(n)){
m--;
n++;
}
return n-m-1;//这里记得-1
}
}
C++:
class Solution {
public:
int subString(string s,int m,int n){
while(m>=0&&n<s.size()&&s[m]==s[n]){ //注意c++字符串定位方法,和数组类似。
m--;
n++;
}
return n-m-1;
}
string longestPalindrome(string s) {
if(s.size()==0||s==" ") return "";
int start=0,end=0,len;
//中心扩展
for(int i=0;i<s.size();i++){
int len1=subString(s,i,i);
int len2=subString(s,i,i+1);
len=max(len1,len2);
if(len>(end-start+1)&&len==len1){
start=i-(len-1)/2;
end=i+(len-1)/2;
}
else if(len>(end-start+1)&&len==len2){
start=i-len/2+1;
end=i+len/2;
}
}
return s.substr(start,end-start+1); //第一个参数是起始位置,第二个参数是子串长度
}
};