随想录日记part43
t i m e : time: time: 2024.04.15
主要内容:今天开始要学习动态规划的相关知识了,今天的内容主要涉及:判断子序列;不同的子序列
动态规划五部曲:
【1】.确定dp数组以及下标的含义
【2】.确定递推公式
【3】.dp数组如何初始化
【4】.确定遍历顺序
【5】.举例推导dp数组
Topic1判断子序列
题目:
思路:
接下来进行动规五步曲:
1.确定dp数组以及下标的含义:
dp[i][j]:长度为[0, i - 1]的s与长度为[0, j - 1]的t的最长公共子序列为dp[i][j]
2.确定递推公式:
主要就是两大情况:1.s[i - 1] 与 t[j - 1]相同 2.s[i - 1] 与 t[j - 1]不相同
如果s[i - 1] 与 t[j - 1]相同,那么找到了一个公共元素,所以dp[i][j] = dp[i - 1][j - 1] + 1;
如果s[i - 1] 与 t[j - 1]不相同,dp[i][j] = dp[i][j - 1];
3.dp数组如何初始化
java
for(int i=0;i<=nums1.length;i++) dp[i][0]=0;
for(int i=0;i<=nums2.length;i++) dp[0][i]=0;
4.确定遍历顺序
外层for循环遍历A,内层for循环遍历B。
5.举例推导dp数组
以输入:text1 = "abcde", text2 = "ace" 为例,dp状态如图:
java
class Solution {
public boolean isSubsequence(String s, String t) {
int n = s.length();
int m = t.length();
if (n > m)
return false;
if (n == 0)
return true;
// dp[i][j] 表示长度为i的序列是否是长度为j的序列的公共最长子序列的长度;
int[][] dp = new int[n + 1][m + 1];
// 初始化
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (s.charAt(i - 1) == t.charAt(j - 1))
dp[i][j] = dp[i - 1][j - 1] + 1;
else
dp[i][j] = dp[i][j - 1];
}
}
if (dp[n][m] == n)
return true;
else
return false;
}
}
时间复杂度 : O ( n ∗ m ) O(n*m) O(n∗m)
空间复杂度 : O ( n ∗ m ) O(n*m) O(n∗m)
Topic2不同的子序列
思路:
接下来进行动规五步曲:
1.确定dp数组以及下标的含义:
dp[i][j]:以i-1为结尾的s子序列中出现以j-1为结尾的t的个数为dp[i][j]
2.确定递推公式:
主要就是两大情况:1.s[i - 1] 与 t[j - 1]相同 2.s[i - 1] 与 t[j - 1]不相同
如果s[i - 1] 与 t[j - 1]相同,dp[i][j] = dp[i - 1][j - 1] + dp[i][j - 1];
如果s[i - 1] 与 t[j - 1]不相同,dp[i][j] = dp[i][j - 1];
3.dp数组如何初始化
java
for(int i=0;i<=nums1.length;i++) dp[i][0]=1;
for(int i=0;i<=nums2.length;i++) dp[0][i]=0;
4.确定遍历顺序
外层for循环遍历A,内层for循环遍历B。
5.举例推导dp数组
以s:"baegg",t:"bag"为例,推导dp数组状态如下:
java
class Solution {
public int numDistinct(String s, String t) {
int n = s.length();
int m = t.length();
if (m > n)
return 0;
int[][] dp = new int[n + 1][m + 1];
for (int i = 0; i < n + 1; i++)
dp[i][0] = 1;
for (int i = 1; i < n + 1; i++) {
for (int j = 1; j < m + 1; j++) {
if (s.charAt(i - 1) == t.charAt(j - 1)) {
dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j]) % ((int) 1e9 + 7);
} else {
dp[i][j] = dp[i - 1][j] % ((int) 1e9 + 7);
}
}
}
return dp[n][m];
}
}
时间复杂度 : O ( n ∗ m ) O(n*m) O(n∗m)
空间复杂度 : O ( n ∗ m ) O(n*m) O(n∗m)