前言
首先第一时间想到了暴力解法,先写判断是否是回文串的函数,然后两层循环不断取字串判断是否是回文串并保留长度最大的那个并返回,但是这种方法时间复杂度太高,过不完Leecode的全部实例。
一、动态规划
区间[i,j]是否是回文串,取决于[i+1,j-1]是否是回文串,这就可以用动态规划。
列出以下状态转移方程:
第一个情况是只有一个字符,当然是回文串。
第二个情况是“AA”或者“aba”,当区间a=a时是回文串。
第三个情况字符串字符数大于=4时,如果第一个和最后一个字符相等,且第二个和倒数第二个相等,则是回文串。
class Solution {
public:
string longestPalindrome(string s) {
string res = s.substr(0,1);//初始化要返回的串
vector<vector<bool>> arr(s.size(),vector<bool>(s.size(),false));//初始化二维数组,存放[i][j]是否是回文串的bool值;
for(int i=s.size()-1;i>=0;i--){
for(int j=i+1;j<s.size();j++){ //因为要去掉首尾判断是否是回文串,所以这里的循环遍历要从二维数组的底部开始
if(i==j){
arr[i][j]=true;//第一个情况
}
else if(j-i<=2){
arr[i][j]=s[i]==s[j];//第二个请款
}
else {
arr[i][j]=(s[i]==s[j])&&arr[i+1][j-1];
}
if(arr[i][j]&&j-i+1>res.size()){
res = s.substr(i,j-i+1);
}
}
}
return res;
}
};
二、中心扩散
动态规划的时间复杂度还是有点高,且空间占用也较大;
class Solution {
public:
string longestPalindrome(string s) {
string res = s.substr(0,1);初始化返回串;
for(int i=0;i<s.size();i++){//循环找寻中心
extendFromCenter(s,i,i);
extendFromCenter(s,i,i+1);
}
return res;
}
extendFromCenter(string& str,int left,int right){
while(str[left]==str[right]&&left>=0&&right<str.size()){
left--;
right++;//扩散
}
if(right-left+1>res.size()){
res = str.substr(left+1,right-1-left);
}
}
}