目录
前沿:撰写博客的目的是为了再刷时回顾和进一步完善,其次才是以教为学,所以如果有些博客写的较简陋,是为了保持进度不得已而为之,还请大家多多见谅。
预:看到题目后的思路和实现的代码。
见:参考答案展示。
感思:对比答案后的思考,与之前做过的题目是否有关联。
行:
(1)对于没做出来的题目,阅读答案后重新做一遍;
(2)下次做题可以尝试改善的方向;
(3)有助于理解的相关的题目
优先级:做题进度>学习&总结>默写回顾>做题数量
题目回顾
动态规划相关章节
代码随想录刷LeetCode | day39 动态规划刷题回顾
动态规划五步法:
- 确定dp数组以及下标的含义
确定递推公式
dp数组如何初始化
确定遍历顺序
举例推导dp数组
1.回文子串
题目链接:647. 回文子串
思路:
什么时候会出现新回文?
当左右两边子串相同时,若里面的子串是回文时,则是新的回文子串。
- 当左右子串相邻or只差一个字符时,只要相同就是回文。
- 相差字符大于1时,则要单独判断内部是否回文。
class Solution {
public int countSubstrings(String s) {
int len = s.length();
boolean[][] dp = new boolean[len][len];
int count = 0;
for(int i = 0;i < len;i++){
for(int j = 0;j <= i;j++){
if(s.charAt(i) == s.charAt(j)){
if(i - j <= 2){
dp[i][j] = true;
count++;
}else{
if(dp[i-1][j+1]){
count++;
dp[i][j] = true;
}
}
}
}
}
return count;
}
}
2.最长回文子序列
题目链接:516. 最长回文子序列
思路
与647. 回文子串区别在于,其考虑内部是否回文时,不需要整个内部都是回文才算,只需要统计内部能够成为回文的数有多少即可。
dp[i][j](i >= j)表示区间[j,i]的最大回文数是多少。
同样的先决判断条件为:左右两边是否相等
- 当左右子串相邻or只差一个字符时,只要相同就是回文。
- 相差字符大于1时,则回文数 = 内部回文数+2。
- 遍历时,要保证内部回文数已更新,则必须 j 遍历时是从大(i)到小(0)遍历。
class Solution {
public int longestPalindromeSubseq(String s) {
int len = s.length();
int[][] dp = new int[len][len];
int result = 0;
for(int i = 0;i < len;i++){
for(int j = i;j >= 0;j--){
if(s.charAt(i) == s.charAt(j)){
if(i - j <= 2){
dp[i][j] = i-j+1;
}else{
dp[i][j] = dp[i-1][j+1]+2;
}
}else{
dp[i][j] = Math.max(dp[i-1][j],dp[i][j+1]);
}
result = Math.max(dp[i][j],result);
}
}
return result;
}
}