代码随想录Day60 | 647. 回文子串 647. 回文子串
- 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子串长度大于2else{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()];}
};