LeetCode 题解工作台
不同的子序列
给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中 t 出现的个数。 测试用例保证结果在 32 位有符号整数范围内。 示例 1: 输入: s = "rabbbit", t = "rabbit" 输出 : 3 解释: 如下所示, 有 3 种可以从 s 中得到 "rabbit" 的方案 。 …
2
题型
6
代码语言
3
相关题
当前训练重点
困难 · 状态·转移·动态规划
答案摘要
我们定义 表示字符串 的前 个字符中,子序列构成字符串 的前 个字符的方案数。初始时 ,其中 $i \in [0,m]$。 当 $i \gt 0$ 时,考虑 的计算:
Interview AiBoxInterview AiBox 实时 AI 助手,陪你讲清 状态·转移·动态规划 题型思路
题目描述
给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中 t 出现的个数。
测试用例保证结果在 32 位有符号整数范围内。
示例 1:
输入:s = "rabbbit", t = "rabbit"输出:3解释: 如下所示, 有 3 种可以从 s 中得到"rabbit" 的方案。rabbbitrabbbitrabbbit
示例 2:
输入:s = "babgbag", t = "bag"输出:5解释: 如下所示, 有 5 种可以从 s 中得到"bag" 的方案。babgbagbabgbagbabgbagbabgbagbabgbag
提示:
1 <= s.length, t.length <= 1000s和t由英文字母组成
解题思路
方法一:动态规划
我们定义 表示字符串 的前 个字符中,子序列构成字符串 的前 个字符的方案数。初始时 ,其中 。
当 时,考虑 的计算:
- 当 时,不能选取 ,因此 ;
- 否则,可以选取 ,此时 。
因此我们有如下的状态转移方程:
最终的答案即为 ,其中 和 分别是字符串 和 的长度。
时间复杂度 ,空间复杂度 。
我们注意到 的计算只和 有关,因此,我们可以优化掉第一维,这样空间复杂度可以降低到 。
class Solution:
def numDistinct(self, s: str, t: str) -> int:
m, n = len(s), len(t)
f = [[0] * (n + 1) for _ in range(m + 1)]
for i in range(m + 1):
f[i][0] = 1
for i, a in enumerate(s, 1):
for j, b in enumerate(t, 1):
f[i][j] = f[i - 1][j]
if a == b:
f[i][j] += f[i - 1][j - 1]
return f[m][n]
复杂度分析
| 指标 | 值 |
|---|---|
| 时间 | complexity is O(n _m) for strings of lengths n and m, as each dp cell is computed once. Space complexity is O(m) with optimization, otherwise O(n_ m). Performance depends on careful DP state updates to avoid overcounting. |
| 空间 | Depends on the final approach |
面试官常问的追问
外企场景- question_mark
Check if the candidate identifies dp[i][j] meaning and proper initialization.
- question_mark
Watch if they correctly implement the state transition without skipping edge cases.
- question_mark
Notice if they attempt space optimization or remain with full 2D table.
常见陷阱
外企场景- error
Confusing character positions and misaligning indices in the dp table.
- error
Forgetting to initialize dp[i][0] = 1, which causes incorrect counts for empty target subsequences.
- error
Overwriting previous dp values during optimization, leading to undercounting.
进阶变体
外企场景- arrow_right_alt
Compute subsequences modulo a large prime to prevent integer overflow.
- arrow_right_alt
Count distinct subsequences that match t but allow at most k skipped characters in between.
- arrow_right_alt
Find the minimum-length subsequence in s that can generate t multiple times.