题目
给你两个字符串 s s s 和 t t t ,统计并返回在 s s s 的 子序列 中 t t t 出现的个数,结果需要对 1 0 9 + 7 10^9 + 7 109+7 取模。
示例:
输入: s = r a b b b i t , t = r a b b i t s = rabbbit, t = rabbit s=rabbbit,t=rabbit
输出: 3 3 3
解释:
如下所示, 有 3 种可以从 s s s 中得到 r a b b i t rabbit rabbit 的方案。
- rabbbit
- rabbbit
- rabbbit
方法
- 动态规划
- 创建二维 d p dp dp 数组, d p [ i ] [ j ] dp[i][j] dp[i][j] 表示 t [ 0 : j − 1 ] t[0:j-1] t[0:j−1] 在 s [ 0 : i − 1 ] s[0:i-1] s[0:i−1] 中出现的次数
- 状态转移
- 边界条件: d p [ i ] [ 0 ] = 1 , d p [ 0 ] [ j ] = 0 dp[i][0]=1,dp[0][j]=0 dp[i][0]=1,dp[0][j]=0
- 若 s [ i − 1 ] = = t [ j − 1 ] s[i-1] == t[j-1] s[i−1]==t[j−1], s [ i − 1 ] s[i-1] s[i−1] 可以选择自己是否跟 t [ j − 1 ] t[j-1] t[j−1] 匹配
- d p [ i ] [ j ] dp[i][j] dp[i][j] 由两部分组成:
- 如果匹配,那么 dp[i][j] 其中一部分数量就是 dp[i-1][j-1]
- 如果选择不匹配(这样可以让前面的字符跟 t [ j − 1 ] t[j-1] t[j−1] 匹配), d p [ i ] [ j ] dp[i][j] dp[i][j] 另外一部分就是 d p [ i − 1 ] [ j ] dp[i-1][j] dp[i−1][j]
- d p [ i ] [ j ] dp[i][j] dp[i][j] 由两部分组成:
- 若 s [ i − 1 ] ! = t [ j − 1 ] s[i-1] != t[j-1] s[i−1]!=t[j−1], d p [ i ] [ j ] = d p [ i − 1 ] [ j ] dp[i][j]=dp[i-1][j] dp[i][j]=dp[i−1][j]
代码
class Solution {
public:int numDistinct(string s, string t) {int n1 = s.size();int n2 = t.size();vector<vector<int>> dp(n1+1, vector<int>(n2+1));for(int i = 0; i < n1; i++)dp[i][0] = 1;for(int i = 1; i <= n1; i++){for(int j = 1; j <= n2; j++){if(s[i-1] == t[j-1]){dp[i][j] = (dp[i-1][j-1] + dp[i-1][j])%(1000000000+7);}else{dp[i][j] = dp[i-1][j];}}}return dp[n1][n2];}
};