647. 回文子串
文档讲解:代码随想录. 回文子串
视频讲解:动态规划,字符串性质决定了DP数组的定义 | LeetCode:647.回文子串
状态:已完成
代码实现
class Solution {
public:int countSubstrings(string s) {vector<vector<int>> dp(s.size(), vector<int>(s.size(), false));int result = 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) {result++;dp[i][j] = true;} else if (dp[i + 1][j - 1]) {//这里是通过之前的状态判断result++;dp[i][j] = true;}}}}return result;}
};
心得体会
- dp[i][j]表示区间【i-j】中的回文串的个数
- 遍历的顺序,从下往上进行遍历,这样保证递推公式能够实现
- 尤其是当间隔相差大于1时的判断方法
516.最长回文子序列
文档讲解:代码随想录. 最长回文子序列
视频讲解:动态规划再显神通,LeetCode:516.最长回文子序列
状态:已完成
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[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;} else {dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);}}}return dp[0][s.size() - 1];}
};
心得体会
- 当i与j相同,那么dp[i][j]一定是等于1的,即:一个字符的回文子序列长度就是1。
- 回文子串是要连续的,回文子序列可不是连续的! 回文子串,回文子序列都是动态规划经典题目。
动态规划总结
动规五部曲分别为:
- 确定dp数组(dp table)以及下标的含义
- 确定递推公式
- dp数组如何初始化
- 确定遍历顺序
- 举例推导dp数组
一开始不太理解上面操作的含义,后来做的多了才发现必要性和适用性,需要反复的理解和思考