动态规划算法汇总链接
题目链接
给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。
一个字符串的 子序列
是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
例如,“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。 两个字符串的 公共子序列
是这两个字符串所共同拥有的子序列。
分析 i 和 j 位置,如果字符相等,那么其区间中的最长公共子序列一定可以以这个字符为结尾;如果不等,再分情况讨论
dp[i][j] 的值有如下情况需要考虑:
text1[i] == text2[j], dp[i-1][j-1] + 1;
text1[i] != text2[j], 对如下值取 max:
dp[i-1][j]
dp[i][j-1]
dp[i-1][j-1] // 实际上这个情况已经被头两种包含了,可以不用写
代码如下:
class Solution {
public:
int longestCommonSubsequence(string text1, string text2) {
int n1 = text1.size() + 1;
int n2 = text2.size() + 1;
text1 = "-" + text1;
text2 = "-" + text2;
vector<vector<int>> dp(n1, vector<int>(n2));
for(int i = 1; i < n1; i++)
for(int j = 1; j < n2; j++)
if (text1[i] == text2[j])
dp[i][j] = dp[i-1][j-1] + 1;
else
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
return dp[n1-1][n2-1];
}
};
题目链接
在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。
现在,可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线,这些直
线需要同时满足满足:
nums1[i] == nums2[j] 且绘制的直线不与任何其他连线(非水平线)相交。
请注意,连线即使在端点也不能相交:每个数字只能属于一条连线。以这种方法绘制线条,并返回可以绘制的最大连线数。
状态表示
略…(这一题和 4.1 根本是一样的,不交叉的连线不就是公共子序列嘛)
代码如下:
class Solution {
public:
int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) {
int n1 = nums1.size() + 1;
int n2 = nums2.size() + 1;
vector<vector<int>> dp(n1, vector<int>(n2));
for(int i = 1; i < n1; i++)
for(int j = 1; j < n2; 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[n1-1][n2-1];
}
};
题目链接
给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中 t 出现的个数,结果需要对 109 + 7 取模。
这一题 hard 在状态表示…
分析区间内的 s 和 t 串,这里如果 s[i] 算作子序列的结尾 dp 是一种情况,如果 s[i] 不算作子序列的结尾 dp 又会是另一种情况,而最终这里的 dp 值应该是这两种情况相加。
dp[i][j] 的值有如下情况需要考虑:
s[i] 算作结尾,而且 s[i] == t[j], dp[i-1][j-1]
s[i] 不算作结尾, dp[i-1][j]
条件满足的情况下:dp[i][j] = dp[i-1][j-1] + dp[i-1][j]
代码如下:
class Solution {
public:
int numDistinct(string s, string t) {
int n1 = s.size() + 1;
int n2 = t.size() + 1;
vector<vector<double>> dp(n1, vector<double>(n2));
dp[0][0] = 1;
for(int i = 1; i < n1; i++)
{
dp[i][0] = 1;
for(int j = 1; j < n2; j++)
dp[i][j] = (s[i-1] == t[j-1]) ?
dp[i-1][j] + dp[i-1][j-1] :
dp[i-1][j];
}
return dp[n1-1][n2-1];
}
};
如果本文对你有些帮助,欢迎 点赞 收藏 关注,你的支持是对作者大大莫大的鼓励!!(✿◡‿◡) 若有差错恳请留言指正~~