力扣_字符串8—不同的子序列

题目

给你两个字符串 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:j1] s [ 0 : i − 1 ] s[0:i-1] s[0:i1] 中出现的次数
    • 状态转移
      • 边界条件: 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[i1]==t[j1] s [ i − 1 ] s[i-1] s[i1] 可以选择自己是否跟 t [ j − 1 ] t[j-1] t[j1] 匹配
        • 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[j1] 匹配), d p [ i ] [ j ] dp[i][j] dp[i][j] 另外一部分就是 d p [ i − 1 ] [ j ] dp[i-1][j] dp[i1][j]
      • s [ i − 1 ] ! = t [ j − 1 ] s[i-1] != t[j-1] s[i1]!=t[j1] d p [ i ] [ j ] = d p [ i − 1 ] [ j ] dp[i][j]=dp[i-1][j] dp[i][j]=dp[i1][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];
    }
};

你可能感兴趣的:(leetcode,算法,职场和发展)