• Leetcode 115.不同的子序列


    不同的子序列

    给定一个字符串 和一个字符串 T,计算在 S 的子序列中 T 出现的个数。

    一个字符串的一个子序列是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如,"ACE" 是 "ABCDE" 的一个子序列,而 "AEC" 不是)

    示例 1:

    输入: S = "rabbbit", T = "rabbit"

    输出: 3

    解释:

    如下图所示, 有 3 种可以从 S 中得到 "rabbit" 的方案。

    (上箭头符号 ^ 表示选取的字母)

    rabbbit

    ^^^^ ^^

    rabbbit

    ^^ ^^^^

    rabbbit

    ^^^ ^^^

    示例 2:

    输入: S = "babgbag", T = "bag"

    输出: 5

    解释:

    如下图所示, 有 5 种可以从 S 中得到 "bag" 的方案。

    (上箭头符号 ^ 表示选取的字母)

    babgbag

    ^^ ^

    babgbag

    ^^ ^

    babgbag

    ^ ^^

    babgbag

    ^ ^^

    babgbag

    ^^^

    动态规划题目。

    以S ="rabbbit",T = "rabbit"为例):

    dp[i][j]表示T的从0开始长度为i的子串和S的从0开始长度为j的子串的匹配的个数。

    比如, dp[2][3]表示T中的ra和S中的rab的匹配情况。

    (1)显然,至少有dp[i][j] = dp[i][j - 1].

    比如, 因为T 中的"ra" 匹配S中的 "ra", 所以dp[2][2] = 1 。 显然T 中的"ra" 也匹配S中的 "rab",所以s[2][3] 至少可以等于dp[2][2]。

    (2) 如果T[i-1] == S[j-1], 那么dp[i][j] = dp[i][j - 1] + (T[i - 1] == S[j - 1] ? dp[i - 1][j - 1] : 0);

    比如, T中的"rab"和S中的"rab"显然匹配,

    根据(1), T中的"rab"显然匹配S中的"rabb",所以dp[3][4] = dp[3][3] = 1,

    根据(2), T中的"rab"中的b等于S中的"rab1b2"中的b2, 所以要把T中的"rab"和S中的"rab1"的匹配个数累加到当前的dp[3][4]中。 所以dp[3][4] += dp[2][3] = 2;

    (3) 初始情况是

    dp[0][0] = 1; // T和S都是空串.

    dp[0][1 ... S.length() ] = 1; // T是空串,S只有一种子序列匹配。

    dp[1 ... T.length() ][0] = 0; // S是空串,T不是空串,S没有子序列匹配。

     1 class Solution{
     2 public:
     3     int numDistinct(string S, string T){
     4         vector<vector<int>> dp(T.length() + 1, vector<int>(S.length() + 1, 0));
     5         dp[0][0] = 1;
     6         for (int i = 1; i<S.length() + 1; i++){
     7             dp[0][i] = 1;
     8         }
     9         for (int i = 1; i<T.length() + 1; i++){
    10             dp[i][0] = 0;
    11         }
    12         for (int i = 1; i<T.length() + 1; i++){
    13             for (int j = 1; j<S.length() + 1; j++){
    14                 dp[i][j] = dp[i][j - 1];
    15                 if (S[j - 1] == T[i - 1]){
    16                     dp[i][j] += dp[i - 1][j - 1];
    17                 }
    18             }
    19         }
    20         return dp[T.length()][S.length()];
    21     }
    22 };
  • 相关阅读:
    联合主键SQL 联合索引
    SQL 对decimal类型转换为int类型
    SQL获取当前时间月份为两位数
    SQL 对结果集进行分组排序过滤重复数据 ROW_NUMBER
    SQL自动流水号函数
    SQL 索引创建
    .Net三层架构
    2016年你应该学习的语言和框架(转)
    MongoDB学习笔记(转)
    干货分享:让你分分钟学会 javascript 闭包(转)
  • 原文地址:https://www.cnblogs.com/kexinxin/p/10163103.html
Copyright © 2020-2023  润新知