题目描述
给你一个字符串 s,找到 s 中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
思路一:暴力法
- 两层for循环再加上判断是否为回文串,时间复杂度为 O ( n 3 ) O(n^3) O(n3)
- 空间复杂度为 O ( 1 ) O(1) O(1),常数个变量
- 设定起始点
i
与子串长度length
,判断从i
开始的长度为length
的子串是否为回文子串,如果是再将该子串长度与目前最长子串长度作对比,将较大值保存,直到length
变为string s
长度
class Solution {
public:
string longestPalindrome(string s) {
if(s.empty()){
return s;
}
int maxlength=0,maxpos=0;
for(int length=1;length<=s.size();length++){
for(int i=0;i<=s.size()-length;i++){
bool judge=true;
for(int j=0;j<length;j++){
if(s[i+j]!=s[i+length-1-j]){
judge=!judge;
break;
}
}
if(judge){
if(maxlength<length){
maxlength=length;;
maxpos=i;
}
}
}
}
return s.substr(maxpos,maxlength);
}
};
思路二:中心扩展
- 加入某个字符串是回文串,那么只要该子串两侧字符相同,那么新子串一定是回文串
- 用
dp[i,j]
表示从第i个到第j个位置的子串是否为回文串
d p [ i , j ] = { t r u e s [ i − 1 ] = = s [ j + 1 ] f a l s e 其他情况 dp[i,j]=\begin{cases}true&s[i-1]==s[j+1]\\false&其他情况\end{cases} dp[i,j]={truefalses[i−1]==s[j+1]其他情况 - 其他情况分两种:1、子串两端字符不同;2、索引位置不合法,如
i
>j
- 考虑边界条件:
- 子串长度为1时,一定是一个回文子串
- 当子串长度为2时,当两个字母相同就是回文子串
- 即: { s [ i , i ] = t r u e s [ i , i + 1 ] = s [ i ] = = s [ i + 1 ] \begin{cases}s[i,i]=true\\s[i,i+1]=s[i]==s[i+1]\end{cases} {s[i,i]=trues[i,i+1]=s[i]==s[i+1]
- 时间复杂度为 O ( n 2 ) O(n^2) O(n2),空间复杂度为O(1),常数个变量
class Solution {
public:
string longestPalindrome(string s) {
int pos=0,length=0;
if(s.empty()){
return s;
}
//考虑长度为1
for(int i=0;i<s.size();i++){
for(int offset=0;i-offset>=0&&i+offset<s.size();offset++){
if(s[i-offset]!=s[i+offset]){
break;
}else{
if(2*offset+1>length){
length=2*offset+1;
pos=i-offset;
}
}
}
}
//考虑长度为2
for(int i=0;i<s.size()-1;i++){
if(s[i]==s[i+1]){
for(int offset=0;i-offset>=0&&i+1+offset<s.size();offset++){
if(s[i-offset]!=s[i+1+offset]){
break;
}
else{
if(2*offset+2>length){
length=2*offset+2;
pos=i-offset;
}
}
}
}
}
return s.substr(pos,length);
}
};