代码随想录Day60 | 647. 回文子串 516.最长回文子序列
647.回文子串
文档讲解:代码随想录
视频讲解: 动态规划,字符串性质决定了DP数组的定义 | LeetCode:647.回文子串
状态

- dp数组
dp[i][j] 表示字符串从i到j的子串是否是回文的 - 递推公式
考虑s[i]和s[j]如果两个相等 且 j-i >1 那么还需要考虑 dp[i+1][j-1]
如果i==j或者j-i == 1 那么可以说明dp[i][j] 是回文的
如果s[i] != s[j] 那么说明dp[i][j]肯定不是回文的 - 初始化
初始为false - 遍历顺序
对于i也就是行需要从下到上,对于j也就是列需要从左到右 - 打印dp
class Solution {
public:
int countSubstrings(string s) {
vector<vector<int>> dp(s.size()+1,vector<int>(s.size()+1,0));
int res = 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;
res++;
}
//j-i > 1子串长度大于2
else
{
dp[i][j] = dp[i+1][j-1];
if(dp[i][j] == 1) res++;
}
}
//s[i]!=s[j]
else dp[i][j] = 0;
}
}
return res;
}
};
516.最长回文子序列
文档讲解:代码随想录
视频讲解: 动态规划再显神通,LeetCode:516.最长回文子序列
状态
子序列与子串,子串必须是连续的,子序列是可以通过删除字符串中的字符获得所以可以理解为不连续的
- dp数组
dp[i][j]表示从i到j的子串中的最长回文子序列 - 递推公式
如果s[i] == s[j] 那么dp[i][j] = dp[i+1][j-1]+2
如果不相等 那么 dp[i][j] = max(dp[i+1][j],dp[i][j-1]),相当于就是只加入s[i]或者s[j]来判断是否存在更长的回文子序列 - 遍历顺序
对于行 从下到上
对于列 从左到右 - 初始化
初始长度都为0 - 打印dp
class Solution {
public:
int longestPalindromeSubseq(string s) {
vector<vector<int>> dp(s.size()+1,vector<int>(s.size()+1,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] = j-i+1;
else
{
dp[i][j] = dp[i+1][j-1]+2;
}
}
else
{
dp[i][j] = max(dp[i][j-1],dp[i+1][j]);
}
}
}
return dp[0][s.size()];
}
};
文章讲述了如何使用动态规划方法解决LeetCode中的两道题目:647.回文子串和516.最长回文子序列,分别通过构造dp数组来判断子串是否为回文以及找到最长回文子序列。
891

被折叠的 条评论
为什么被折叠?



