题目描述
给你一个字符串 s,找到 s 中最长的回文子串。
最长回文子串
示例
示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例2:
输入:s = “cbbd”
输出:“bb”
C++代码 暴力求解法
class Solution {
public:
string longestPalindrome(string s) {
string ans,temp;
int maxlen=0;
for(int i=0;i<s.length();i++){
for(int j=s.length()-i;j>0;j--){
temp = s.substr(i,j);
//cout<<temp<<endl;
if(Isornot(temp)){
if(temp.length()>=maxlen){
maxlen = temp.length();
ans = temp;
}
}
}
}
return ans;
}
int Isornot(string T){
string S(T.rbegin(),T.rend());
if(S == T) return 1;
else return 0;
}
};
该方法就是使用了暴力求解法,即从字符串s的第一个字符开始截取后续字符作为检验最长回文子串的子字符串,以确保字符串中所有连续子字符串可以被检测,Isornot函数即将字符串倒序后与原字符串进行比较。
这种暴力求解法在Leetcode上时间是超时的,但答案是正确的。后续还需对代码进行改进,降低时间复杂度。
- 最长公共子串
- 动态规划法
- 中心扩展法
这里值得注意的一点是:
substr这个函数的参数的含义为:substr(int begin,int length),太久没使用导致忘记了,即指定开始位置,从开始位置截取长度为length的字符串。
C++代码 中心扩展法
class Solution {
public:
string longestPalindrome(string s) {
int maxlen = 0;
int begin=0,end=0;
for(int i=0;i<s.length();i++){
int len1=expand(s,i,i);
int len2=expand(s,i,i+1);
maxlen = max(max(len1,len2),maxlen);
if(maxlen>end-begin+1){
begin = i-(maxlen-1)/2;
end = i+maxlen/2;
}
}
return s.substr(begin,maxlen);
}
int expand(string s,int left,int right){
while(left>=0 && right<s.length() && s[left]==s[right]){
left--;
right++;
}
return right-left-1;
}
};
回文中心的两侧互为镜像。因此,回文可以从他的中心展开,并且只有 2n-1 个这样的中心(一个元素为中心的情况有 n 个,两个元素为中心的情况有 n-1 个)。