LeetCode题目,115. Distinct Subsequences
先看题目描述
大意就是给定一个字符串 s 和字符串 t,让我们计算 s 中与 t 相等的子序列个数并返回
算法和思路
动态规划
这题看着比较难,但其实只要想到可以用动态规划解决,想明白状态转移方程和边界条件,这道题就很好解决
设字符串 s 的长度为 n,字符串 t 的长度为 m,构建一个长度为 m + 1,宽度为 n + 1 的二维数组 dp
- 状态方程定义:dp[i][j] 表示字符串 s[0:j - 1] 中与 t[0:i - 1] 相等的子序列的数量
- 状态转移方程:
- 若 t[i - 1] 与 s[j - 1] 相等,则 dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1]
- 否则,dp[i][j] = dp[i][j - 1]
为了方便状态转移,初始化时将 dp[0] 的所有元素都置为 1,最后返回 dp[m][n] 即可
关于对状态转移方程的理解:当 t[i - 1] 与 s[j - 1] 不相等时,t[i - 1] 与 s[j - 1] 不匹配,因此只考虑 t[0:i - 1] 作为 s[0:j - 2] 的子序列,因此有 dp[i][j] = dp[i][j - 1];当 t[i - 1] 与 s[j - 1] 相等时,此时有两种选择,一种是 t[i - 1] 与 s[j - 1] 不匹配,这部分对 dp[i][j] 的贡献是 dp[i][j - 1],另一种是 t[i - 1] 与 s[j - 1] 匹配,此时要考虑 t[0:i - 2] 作为 s[0:j - 2] 的子序列,这部分对 dp[i][j] 的贡献是 dp[i - 1][j - 1],因此有 dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1]
算法源码
动态规划
1 | class Solution { |