一、判断是否为回文子串
(一)dp[i][j]为从下标i到下标j这一范围内的字符串是否为回文子串
(二)满足当前字符串为回文,或者区间内为回文,dp[i][j]=1
(三)初始化,全都为false
(四)遍历顺序,从左到右,从下到上(因为i j 需要从i+1 j-1推过来)
class Solution {
public:
int countSubstrings(string s) {
vector<vector<bool>>dp(s.size(),vector<bool>(s.size(),0));
int result=0;
for(int i=s.size()-1;i>=0;i--){
for(int j=i;j<=s.size()-1;j++){
if(s[i]==s[j]){
if(j-i<=1){
dp[i][j]=1;
result++;
}
else if(dp[i+1][j-1]==1){
dp[i][j]=1;
result++;
}
}
}
}
return result;
}
};
二、最长回文子序列
分析递推公式:dp[i][j]=1(一个字母一定为回文)
dp[i][j]=dp[i+1][j-1]+2(中间的最大长度在加两边的端点)
dp[i][j]=max(dp[i+1][j],dp[i][j-1]);(取去掉一侧后的最大回文子串数,因为去掉了有可能是回文,但不去掉一定不是回文)
class Solution {
public:
int longestPalindromeSubseq(string 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(i==j)dp[i][j]=1;
else dp[i][j]=dp[i+1][j-1]+2;
}
else{
dp[i][j]=max(dp[i+1][j],dp[i][j-1]);
}
}
}
return dp[0][s.size()-1];
}
};