「代码随想录算法训练营」第四十天 | 动态规划 part13
1.「代码随想录算法训练营」第二天 | 数组 part22.「代码随想录算法训练营」第三天 | 链表 part13.「代码随想录算法训练营」第四天 | 链表 part24.「代码随想录算法训练营」第一天(补) | 数组 part15.「代码随想录算法训练营」第五天 | 哈希表 part16.「代码随想录算法训练营」第六天 | 哈希表 part27.「代码随想录算法训练营」第七天 | 字符串 part18.「代码随想录算法训练营」第八天 | 字符串 part29.「代码随想录算法训练营」第九天 | 栈与队列 part110.「代码随想录算法训练营」第十天 | 栈与队列 part211.「代码随想录算法训练营」第十一天 | 二叉树 part112.「代码随想录算法训练营」第十二天 | 二叉树 part213.「代码随想录算法训练营」第十三天 | 二叉树 part314.「代码随想录算法训练营」第十四天 | 二叉树 part415.「代码随想录算法训练营」第十五天 | 二叉树 part516.「代码随想录算法训练营」第十六天 | 二叉树 part617.「代码随想录算法训练营」第十七天 | 二叉树 part718.「代码随想录算法训练营」第十八天 | 二叉树 part819.「代码随想录算法训练营」第十九天 | 回溯算法 part120.「代码随想录算法训练营」第二十天 | 回溯算法 part221.「代码随想录算法训练营」第二十一天 | 回溯算法 part322.「代码随想录算法训练营」第二十二天 | 回溯算法 part423.「代码随想录算法训练营」第二十三天 | 贪心算法 part124.「代码随想录算法训练营」第二十四天 | 贪心算法 part225.「代码随想录算法训练营」第二十五天 | 贪心算法 part326.「代码随想录算法训练营」第二十六天 | 贪心算法 part427.「代码随想录算法训练营」第二十七天 | 贪心算法 part528.「代码随想录算法训练营」第二十八天 | 动态规划 part129.「代码随想录算法训练营」第二十九天 | 动态规划 part230.「代码随想录算法训练营」第三十天 | 动态规划 part331.「代码随想录算法训练营」第三十一天 | 动态规划 part432.「代码随想录算法训练营」第三十二天 | 动态规划 part533.「代码随想录算法训练营」第三十三天 | 动态规划 part634.「代码随想录算法训练营」第三十四天 | 动态规划 part735.「代码随想录算法训练营」第三十五天 | 动态规划 part836.「代码随想录算法训练营」第三十六天 | 动态规划 part937.「代码随想录算法训练营」第三十七天 | 动态规划 part1038.「代码随想录算法训练营」第三十八天 | 动态规划 part1139.「代码随想录算法训练营」第三十九天 | 动态规划 part1240.「代码随想录算法训练营」第四十一天 | 单调栈 part1
41.「代码随想录算法训练营」第四十天 | 动态规划 part13
42.「代码随想录算法训练营」第四十二天 | 单调栈 part243.「代码随想录算法训练营」第四十三天 | 图论 part144.「代码随想录算法训练营」第四十四天 | 图论 part245.「代码随想录算法训练营」第四十五天 | 图论 part346.「代码随想录算法训练营」第四十六天 | 图论 part447.「代码随想录算法训练营」第四十七天 | 图论 part548.「代码随想录算法训练营」第四十八天 | 图论 part649.「代码随想录算法训练营」第四十九天 | 图论 part750.「代码随想录算法训练营」第五十天 | 图论 part851.「代码随想录算法训练营」第五十一天 | 图论 part952.「代码随想录算法训练营」第五十二天 | 图论 part1053.「代码随想录算法训练营」完结!647. 回文子串
题目链接:https://leetcode.cn/problems/palindromic-substrings/
文章讲解:https://programmercarl.com/0647.回文子串.html
题目难度:中等
视频讲解:https://www.bilibili.com/video/BV17G4y1y7z9/
题目状态:看题解
思路一:动态规划
使用一个二维动规数组dp[i][j]
来保存从s[i]
到s[j]
(或从s[j]
到s[i]
,一样的,本题代码是从j到i)是否属于回文子串。两层遍历该字符串,来记录回文子串的个数。
- 当
s[i] == s[j]
时,要判断一下i
和j
的距离,若i和j的距离为0和1,则表示这是一个回文子串。 - 当
s[i] == s[j]
时,但i
和j
的距离较大,那么就要看其里面的一个是不是回文子串。
代码一:
class Solution { public: int countSubstrings(string s) { int len = s.size(); vector<vector<bool>> dp(len, vector<bool>(len, false)); int ans = 0; for(int i = len - 1; i >= 0; --i) { for(int j = i; j < len; ++j) { if(s[i] == s[j]) { if(j - i <= 1) { ans++; dp[i][j] = true; } else if(dp[i + 1][j - 1]){ ans++; dp[i][j] = true; } } } } return ans; } };
思路二:双指针
使用一个辅助函数extend
来遍历有多少子串,其中i和j分别是两个起点指针,两个指针分别向前和向后遍历,如果遇到i不等于j的时候,就可以返回了,结果就是以i和j为中间点的子串有多少。而在主函数中,两次调用extend
函数分别表示奇子串和偶子串。
代码二:
class Solution { public: int countSubstrings(string s) { int ans = 0; for(int i = 0; i < s.size(); ++i) { ans += extend(s, i, i, s.size()); ans += extend(s, i, i + 1, s.size()); } return ans; } int extend(const string &s, int i, int j, int n) { int ans = 0; while(i >= 0 && j < n && s[i] == s[j]) { i--; j++; ans++; } return ans; } };
516. 最长回文子序列
题目链接:https://leetcode.cn/problems/longest-palindromic-subsequence/
文章讲解:https://programmercarl.com/0516.最长回文子序列.html
题目难度:中等
视频讲解:https://www.bilibili.com/video/BV1d8411K7W6/
题目状态:看题解
思路:
维护一个动规数组dp[i][j]
表示从s[i]
到s[j]
的最长回文子序列的大小。
- 当
s[i] == s[j]
时,表示其是一个回文序列,因此将这两个字符加入进来,即dp[i][j] = dp[i + 1][j - 1] + 2
。 - 当
s[i] != s[j]
时,我们就需要找在这个范围里的最大子序列的个数了。
代码:
class Solution { public: int longestPalindromeSubseq(string s) { int len = s.size(); vector<vector<int>> dp(len, vector<int>(len, 0)); for(int i = 0; i < len; ++i) dp[i][i] = 1; for(int i = len - 1; i >= 0; --i) { for(int j = i + 1; j < len; ++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][len - 1]; } };
动态规划总结
合集:
「代码随想录算法训练营」
分类:
算法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?