392.判断子序列
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
卡哥版本的思路:就是寻找公共子序列。
dp数组:dp[i][j] 表示以下标i-1为结尾的字符串s,和以下标j-1为结尾的字符串t,相同子序列的长度为dp[i][j]。
递推公式:if (s[i - 1] == t[j - 1]),那么dp[i][j] = dp[i - 1][j - 1] + 1; if (s[i - 1] != t[j - 1]),此时相当于t要删除元素,t如果把当前元素t[j - 1]删除,那么dp[i][j] 的数值就是 看s[i - 1]与 t[j - 2]的比较结果了,即:dp[i][j] = dp[i][j - 1];
我的版本思路:01背包的思路。s是背包,如果物品(t里的元素)能装满s,也就是组成s。那s就是t的子序列。
dp数组:dp[j] 表示用当前物品能否组成字符串s[j-1]。空物品可以装满空背包,因此第一个元素为True
递推公式:if (s[i - 1] == t[j - 1]) and dp[j-1],意味着之前的物品可组成前一个背包,那现在这个元素也与背包适应,则True
遍历顺序:因为是一维数组,01背包,物品外层,背包内层,逆序遍历。
115.不同的子序列
给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数。
思路:
dp数组:以i-1为结尾的s子序列中出现以j-1为结尾的t的个数为dp[i][j]。初始化:当背包为空时,不管有没有物品,都有一种方法装满空背包。
确定递推:一部分:不考虑当前s子串和t子串的最后一位字母,前面都配好的,此时新的字符配上了,因此有 dp[i-1][j-1]。另一部分:不用新字符s[i - 1]来匹配,个数为dp[i - 1][j]。所以当s[i - 1] 与 t[j - 1]相等时,dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]
二维数组:
一维数组:
以下是卡哥资料
392.判断子序列
这道题目算是 编辑距离问题 的入门题目(毕竟这里只是涉及到减法),慢慢的,后面就要来解决真正的 编辑距离问题了
https://programmercarl.com/0392.%E5%88%A4%E6%96%AD%E5%AD%90%E5%BA%8F%E5%88%97.html
115.不同的子序列
但相对于刚讲过 392.判断子序列,本题 就有难度了 ,感受一下本题和 392.判断子序列 的区别。
https://programmercarl.com/0115.%E4%B8%8D%E5%90%8C%E7%9A%84%E5%AD%90%E5%BA%8F%E5%88%97.html