zoukankan      html  css  js  c++  java
  • Distinct Subsequences

    题目: 给定两个string (S)(T),计算序列为(T)(S)的子序列的数量。

    例如S = "rabbbit", T = "rabbit",返回结果为3
    子序列:例如,"ACE"是"ABCDE"的子序列。

    这里我用动态规划的来求解

    • 构建DP表,大小为 (T.size + 1)行,(S.size + 1)
      +1是为了后面查表方便。
    • 第一次,填表:判断T[j] 是否 等于 S[i] 。1代表相同,0代表不同
    • 第二次,查表:从T[1]到T[end] 有几种走法
      走法:从1到1,走也是有条件的,只能走自己的斜下方的方向,不能垂直向下,向右走
      有几种走法即有几个子序列
      计算有几种走法可以用递归,但效率较低,可用循环。
    ![](https://images0.cnblogs.com/blog/661985/201502/152113244487788.png)
    

    代码中的查表为从后向前

    下面为C++代码

    int numDistinct(string S, string T) {
       int num_T = T.size(), num_S = S.size();
       if (num_S < num_T) return 0;
    
       vector<vector<int>>  DP(num_T + 1, vector<int>(num_S + 1, 0)); //初始化DP表,全为0
       for (int i = 0; i < num_S; ++i){   // DP表第一行为1,最后一个为0
          DP[0][i] = 1;
       }
       // DP 填表
       for (int j = 1; j < num_T + 1; ++j){
          for (int i = j; i < num_S + 1; ++i){
             if (T[j - 1] == S[i - 1]){
                DP[j][i] = 1; 
             }
          }
       }
       // 查表,计算得到结果
       for (int j = num_T; j > 0; --j){
          int nn = 0;
          for (int i = num_S - (num_T - j); i > 0; --i){ 
             nn += DP[j][i];
             if (DP[j - 1][i - 1] >= 1){
                DP[j - 1][i - 1] = nn;
             }
          }
       }
       return DP[0][0];
    }
    

    时间复杂度 (O(n*m))

    空间(O(n*m))

  • 相关阅读:
    1,巡检脚本pexpect
    Cisco胖AP配置上网
    阿里云服务器更换密钥后,无论以何种远程连接方式都连接不上
    [PAT乙级题解]——A+B和C
    研究ThreadLocal类
    Java的反射机制
    volatile浅析
    Java 对称数据加密AES
    Java使用非对称数据加密RSA
    练习-登陆接口
  • 原文地址:https://www.cnblogs.com/iois/p/4293388.html
Copyright © 2011-2022 走看看