115. 不同的子序列¶
给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中 t 出现的个数。
测试用例保证结果在 32 位有符号整数范围内。
示例 1:
| Text Only | |
|---|---|
示例 2:
| Text Only | |
|---|---|
提示:
1 <= s.length, t.length <= 1000s和t由英文字母组成
个人题解¶
动态规划¶
dp[i][j]表示区间[0, i - 1]的s子序列中出现区间[0, j - 1]的t的个数;- 初始化
dp:长度为0的t显然在s的子序列中出现次数为1;长度为0的s子序列长度也为0,那么t不可能在s子序列中出现; - 状态转移:当前字符匹配:
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j],当前字符不匹配:dp[i][j] = dp[i - 1][j]- 对于
s[i - 1] == t[j - 1],即当前位置字符匹配,t中[0, j - 1]部分和[0, j - 2]部分的出现次数相同,因为满足s[i - 1] == t[j - 1]后,t前面部分[0, j - 2]是在dp[i - 1][j - 1]状态的方式下匹配的,所以算作一种匹配方式,即dp[i][j] = dp[i - 1][j - 1]; - 还有一种情况:虽然
s[i - 1] == t[j - 1]但不将当前字符作为匹配项,而是等待使用s后续项进行匹配,即dp[i - 1][j]; - 对于
s[i - 1] != t[j - 1]:同上述的第二种情况。
- 对于
对于状态转移推导中 s[i - 1] == t[j - 1] 的第二种情况举例说明:
假设 s = "yuelaii", t = "yuelai" 那么显然有两类匹配方式(分别对应上述推导中的两类):
s中[0, 5]子序列 与t匹配;s中[0, 4]及s[6]组成的子序列与t匹配。