115.不同的子序列

【LetMeFly】115.不同的子序列

力扣题目链接:https://leetcode.cn/problems/distinct-subsequences/

给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数。

字符串的一个 子序列 是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如,"ACE" 是 "ABCDE" 的一个子序列,而 "AEC" 不是)

题目数据保证答案符合 32 位带符号整数范围。

 

示例 1:

输入:s = "rabbbit", t = "rabbit"
输出3
解释:
如下图所示, 有 3 种可以从 s 中得到 "rabbit" 的方案rabbbit
rabbbit
rabbbit

示例 2:

输入:s = "babgbag", t = "bag"
输出5
解释:
如下图所示, 有 5 种可以从 s 中得到 "bag" 的方案babgbag
babgbag
babgbag
babgbag
babgbag

 

提示:

  • 0 <= s.length, t.length <= 1000
  • st 由英文字母组成

方法一:动态规划

$dp[i][j]$:s的前i个字符的子串的子序列中,t的前j个字符的子串出现的次数

转移方程:

$\begin{cases}dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]& \text{ if } s[i]=s[j] \dp[i][j] = dp[i - 1][j]& \text{ if } s[i]\neq s[j] \end{cases}$

初始值$dp[i][0]=1$(T为空的时候,方案数为1)

  • 时间复杂度$O(mn)$,其中$m=s.size(), n=t.size()$
  • 空间复杂度$O(mn)$

AC代码

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public:
int numDistinct(string s, string t) {
/* dp[i][j]:```s的前i个字符的子串```的子序列中,```t的前j个字符的子串```出现的次数 */
vector<vector<unsigned int>> dp(s.size() + 1, vector<unsigned int>(t.size() + 1, 0));
for (int i = 0; i < s.size() + 1; i++) { // T为空的时候,方案数为1
dp[i][0] = 1;
}
for (int i = 1; i < s.size() + 1; i++) {
for (int j = 1; j < t.size() + 1; j++) {
if (s[i - 1] == t[j - 1])
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
else
dp[i][j] = dp[i - 1][j];
}
}
return dp.back().back();
}
};

同步发文于CSDN,原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/125820358


115.不同的子序列
https://blog.letmefly.xyz/2022/07/16/LeetCode 0115.不同的子序列/
作者
Tisfy
发布于
2022年7月16日
许可协议