115. 不同的子序列
给定一个字符串 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
s
和t
由英文字母组成
brute force
TLE
class Solution: def numDistinct(self, s: str, t: str) -> int: res=0 comb=itertools.combinations(s,len(t)) for i in comb: i=''.join(i) if i==t: res+=1 return res
then let's try DP
dp[i][j] 表示s中范围是 [0, i] 的子串中能组成t中范围是 [0, j] 的子串的子序列的个数
分析例子
r a b b b i t
1 1 1 1 1 1 1 1
r 0 1 1 1 1 1 1 1
a 0 0 1 1 1 1 1 1
b 0 0 0 1 2 3 3 3
b 0 0 0 0 1 3 3 3
i 0 0 0 0 0 0 3 3
t 0 0 0 0 0 0 0 3
总结规律 就出来了
class Solution: def numDistinct(self, s: str, t: str) -> int: m,n=len(s),len(t) dp=[[0]*(m+1) for i in range(n+1)] for i in range(m): dp[0][i]=1 for i in range(1,n+1): for j in range(1,m+1): if t[i-1]==s[j-1]: dp[i][j]=dp[i][j-1]+dp[i-1][j-1] else: dp[i][j]=dp[i][j-1] return dp[n][m]