文章目录
- 第九章 动态规划 Part 11
- 1143. 最长公共子序列
- 1035. 不相交的线
- 53. 最大子序和
- 392. 判断子序列
第九章 动态规划 Part 11
1143. 最长公共子序列
体会一下本题和 718. 最长重复子数组 的区别。
视频讲解:B站视频
题解链接:最长公共子序列题解
结合这两张图进行分析。定义 dp[i][j]
表示 text1
的前 i
个字符和 text2
的前 j
个字符的最长公共子序列长度,不断斜向下判断下能否再加一。不能的话,继承上个或者左边的值。整体难度不大。
1035. 不相交的线
其实本题和 1143. 最长公共子序列 是一模一样的,大家可以尝试自己做一做。
视频讲解:B站视频
题解链接:不相交的线题解
看题目思考了一会,才发现这题不和上题一模一样吗?只不过一个是字符串,一个是数组。简单。秒杀
class Solution {
public:int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) {vector<vector<int>> dp(nums1.size() + 1, vector<int>(nums2.size() + 1, 0));for (int i = 1; i <= nums1.size(); i++) {for (int j = 1; j <= nums2.size(); j++) {if (nums1[i - 1] == nums2[j - 1]) {dp[i][j] = dp[i - 1][j - 1] + 1;} else {dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);}}}return dp[nums1.size()][nums2.size()];}
};
53. 最大子序和
这道题我们之前用贪心算法做过,这次我们可以再用动态规划来做一遍。
视频讲解:B站视频
题解链接:最大子序和题解
class Solution {
public:int maxSubArray(vector<int>& nums) {vector<int>dp(nums.size(),0); dp[0]=nums[0];int result = nums[0];for(int i=1;i<nums.size();i++){dp[i] = max(dp[i - 1] + nums[i], nums[i]);result = (result > dp[i]) ? result : dp[i];}return result;}
};
只要知道递归公式:dp[i] = max(dp[i - 1] + nums[i], nums[i]);这题还是挺简单的。当然最难得还是注意最后的结果可不是dp[nums.size() - 1],因为dp[i]保存的是包含
nums[i]后最大子序列和。所以还得挑最大的。
392. 判断子序列
这道题可以算作 编辑距离问题 的入门题目(毕竟这里只是涉及到减法)。慢慢的,后面我们会解决真正的 编辑距离问题。
题解链接:判断子序列题解
class Solution {
public:bool isSubsequence(string s, string t) {if(s.size()>t.size())return false;
vector<vector<int>> dp(s.size() + 1, vector<int>(t.size() + 1, 0));for (int i = 1; i <= s.size(); i++) {for (int j = 1; j <= t.size(); j++) {if (s[i - 1] == t[j - 1]) {dp[i][j] = dp[i - 1][j - 1] + 1;} else {dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);}}}return dp[s.size()][t.size()]==s.size();}
};
这一题和第一题也是几乎一模一样,挺简单的。改下return 值即可。