5.最长回文子串
示例 1:
输入:s = "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd" 输出:"bb"
思路:
如果一个串是回文子串,那么在去掉最外层两个字符后也是回文子串(比如“cabac”和“aba”)。
需要做的,就是使用一个二维数组来记录结果,再遍历进行判断。
如果是一个字符,那么它肯定是回文子串;如果是两个字符,则判断依照它们之间的间距来进一步判断(具体内容可见代码中注释)。
因为接下来的代码是从短的串判断到长的串,所以并不需要在进一步判断是递归判断。
代码:
class Solution {
public:
string longestPalindrome(string s) {
int maxLen = 0;
int begin = 0;
int end = 0;
if(s.size()==1) return s;//只有一个字符的肯定是回文子串
vector<vector<int>> dp(s.size(),vector<int>(s.size(),0));
for(int i = s.size()-1;i>=0;i--){//从末尾开始,往前
for(int j = i;j<s.size();j++){//从末尾开始,往后
if(s[i]==s[j]){//两个字符相等
if(j-i<=1){//相邻或是同一个
dp[i][j]=1;
}
else if(dp[i+1][j-1]){//去掉最外层两个,看真假
dp[i][j]=1;
}
}
if(dp[i][j]&&maxLen<j-i+1){//如果结果真,且长度更长
maxLen = j-i+1;
begin = i;
end = j;
}
}
}
return s.substr(begin,end-begin+1);//返回子串
}
};
代码还可以优化!
516.最长回文子序列
示例 1:
输入:s = "bbbab" 输出:4 解释:一个可能的最长回文子序列为 "bbbb" 。
示例 2:
输入:s = "cbbd" 输出:2 解释:一个可能的最长回文子序列为 "bb" 。
思路:
与上一题类似,不过此处使用二维数组来记录最长子序列的大小。
代码:
class Solution {
public:
int longestPalindromeSubseq(string s) {
//用二维数组记录当前下标所包含的串的最长子序列长度
vector<vector<int>> dp(s.size(),vector<int>(s.size(),0));
for(int i=0;i<s.size();i++){//初始化dp数组,一个字符肯定是回文子序列
dp[i][i]=1;
}
for(int i=s.size()-1;i>=0;i--){
for(int j=i+1;j<s.size();j++){//由短到长
if(s[i]==s[j]){//两位置相等
dp[i][j]=dp[i+1][j-1]+2;//在记录去掉最外层的数组的值的基础上加2
}
else{//不等,取之前记录过的最大值
dp[i][j]=max(dp[i][j-1],dp[i+1][j]);
}
}
}
return dp[0][s.size()-1];//返回从头到位记录的最大值
}
};