提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
提示:这里可以添加本文要记录的大概内容:
今天是跟着代码随想录刷题的第52天,主要学习了回文子串和最长回文子序列
提示:以下是本篇文章正文内容,下面案例可供参考
一、回文子串
思路:
这道题dp【i】【j】等于0或者1,如果是0就说明不是回文,如果是1就是回文,核心思路是,如果首和尾相等,这时候需要判断情况,如果首尾相差小于等于2,就做对应的行为,如果大于2,就看中间的是不是也是回文,如果是那么整个就是回文,回文对应的数量要加1,因为最后是求回文的子串一共有多少个。注意要根据dp[i+1][j-1]==1这里能看出来遍历的顺序,i需要从后向前遍历,j需要从前向后遍历。
代码:
cpp
class Solution {
public:
int countSubstrings(string s) {
vector<vector<int>> dp(s.size(),vector<int>(s.size(),0));
int huiwen=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||j==i+1||j==i+2)
{
dp[i][j]=1;
huiwen++;
}
else
{
if(dp[i+1][j-1]==1)//从这里可以看出遍历顺序,
{
dp[i][j]=1;
huiwen++;
}
}
}
}
}
return huiwen;
}
};
二、最长回文子序列
思路:
这道题的dp【i】【j】是字符串s在i,j范围内最长的回文子序列的长度,这时候同样是分左右相等或者不相等的情况,如果相等,并且首位差大于1的话,就是去掉首尾的最长长度加2(一个首一个尾),主要是这里主要是关注不相等,那么首尾分别缩进一下看哪个更大,dp[i][j]=max(dp[i+1][j],dp[i][j-1])
代码:
cpp
class Solution {
public:
int longestPalindromeSubseq(string s) {
vector<vector<int>> dp(s.size(),vector<int>(s.size(),0));
int max1=INT_MIN;
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]=j-i+1;
}
else
{
dp[i][j]=dp[i+1][j-1]+2;
}
}
else
{
dp[i][j]=max(dp[i+1][j],dp[i][j-1]);
}
max1=max(dp[i][j],max1);
}
}
return max1;
}
};