给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列的长度。
视频讲解https://www.bilibili.com/video/BV1ye4y1L7CQ文章讲解
https://programmercarl.com/1143.%E6%9C%80%E9%95%BF%E5%85%AC%E5%85%B1%E5%AD%90%E5%BA%8F%E5%88%97.html
- 思路:
- dp数组含义:
- dp[i][j]:text1的子串[0, i - 1] 与 text2的子串[0, j - 1] 的最长公共子序列的长度
- 递推公式:
- text1[i - 1] 与 text2[j - 1]相同:dp[i][j] = dp[i - 1][j - 1] + 1;
- text1[i - 1] 与 text2[j - 1]不同:dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
- 初始化:全0
- test1[0, i-1]和空串的最长公共子序列是0👉dp[i][0] = 0
- 同理dp[0][j] = 0
- 遍历顺序:从上到下,从左到右
- 最终结果:dp[text1.size()][text2.size()]
- dp数组含义:
- 代码:
class Solution {
public:
int longestCommonSubsequence(string text1, string text2) {
vector<vector<int>> dp(text1.size() + 1, vector<int>(text2.size() + 1, 0));
for (int i = 1; i <= text1.size(); i++) {
for (int j = 1; j <= text2.size(); j++) {
if (text1[i - 1] == text2[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[text1.size()][text2.size()];
}
};
我们在两条独立的水平线上按给定的顺序写下 A 和 B 中的整数。现在,我们可以绘制一些连接两个数字 A[i] 和 B[j] 的直线,只要 A[i] == B[j],且我们绘制的直线不与任何其他连线(非水平线)相交。以这种方法绘制线条,并返回我们可以绘制的最大连线数。
视频讲解https://www.bilibili.com/video/BV1h84y1x7MP文章讲解
https://programmercarl.com/1035.%E4%B8%8D%E7%9B%B8%E4%BA%A4%E7%9A%84%E7%BA%BF.html
- 思路:最大不相交连线数👉最长公共子序列的长度
- 代码:
class Solution {
public:
int maxUncrossedLines(vector<int>& A, vector<int>& B) {
vector<vector<int>> dp(A.size() + 1, vector<int>(B.size() + 1, 0));
for (int i = 1; i <= A.size(); i++) {
for (int j = 1; j <= B.size(); j++) {
if (A[i - 1] == B[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[A.size()][B.size()];
}
};
LeetCode 53. 最大子数组和(动态规划)
给定一个整数数组 nums ,找到一个具有最大和的子数组(子数组最少包含一个元素),返回其最大和。子数组 是数组中的一个连续部分。
视频讲解https://www.bilibili.com/video/BV19V4y1F7b5文章讲解
https://programmercarl.com/0053.%E6%9C%80%E5%A4%A7%E5%AD%90%E5%BA%8F%E5%92%8C%EF%BC%88%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%EF%BC%89.html
- 思路:
- dp数组含义:
- dp[i]:以nums[i]结尾的最大子数组和
- 递推公式:dp[i] = max(dp[i - 1] + nums[i], nums[i]);
- 初始化:dp[0] = nums[0]
- 遍历顺序:从前向后
- 最终结果:dp数组的最大值
- dp数组含义:
- 代码:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if (nums.size() == 0) return 0;
vector<int> dp(nums.size());
dp[0] = nums[0];
int result = dp[0];
for (int i = 1; i < nums.size(); i++) {
dp[i] = max(dp[i - 1] + nums[i], nums[i]); // 状态转移公式
if (dp[i] > result) result = dp[i]; // result 保存dp[i]的最大值
}
return result;
}
};
// 时间复杂度:O(n)
// 空间复杂度:O(n)