zoukankan      html  css  js  c++  java
  • leetcode[115] Distinct Subsequences

    给定字符串S和T,S通过删除某些位置的字符得到T的话,就记作一种subSequence。返回总共有几种。

    Given a string S and a string T, count the number of distinct subsequences of T in S.

    A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, "ACE" is a subsequence of "ABCDE" while "AEC" is not).

    Here is an example:
    S = "rabbbit", T = "rabbit"

    Return 3.

    思路一:分分钟就写出了递归的算法。

    class Solution {
    public:
        int numDistinct(string S, string T)
        {
            if (S.size() < T.size()) return 0;
            if (S.size() == T.size() && S == T) return 1; // 都为空的时候返回什么呢???
            if (S[0] != T[0])
                return numDistinct(S.substr(1), T);
            else
                return numDistinct(S.substr(1), T.substr(1)) + numDistinct(S.substr(1), T);
        }
    };

    Time Limited

    思路二:这样的题都是可以用动态规划解决的。

    用dp[i][j]记录S的前i个和T的前j个的符合个数,那么最后目标就是dp[S.size()][T.size()];

    初始化,j = 0 时候,dp[i][0] = 1,因为所有的都可以通过删除所有变成空字符,并且只有一种。

    递推式子如下了:

    i和j都从1开始,且j不能大于i,因为匹配的长度至少为1开始,j大于i无意义

    如果 i == j  那么 dp[i][j] = S.substr(0, i) == T.substr(0, j);

    如果 i != j 分两种情况

      S[i-1] != T[j-1] 时,也就是加入不加入i的影响是一样的,那么 dp[i][j] = dp[i - 1][j];

      S[i-1] == T[j-1] 时,那么当前字符可选择匹配或者是不匹配,所以dp[i][j] = dp[i - 1][j -1] + dp[i - 1][j];

    整理成代码:

    class Solution {
    public:
        int numDistinct(string S, string T)
        {
            int lenS = S.size(), lenT = T.size();
            if (lenS < lenT) return 0;
            if (lenT == 0) return lenS;
            
            int dp[lenS + 1][lenT + 1];
            //memset(dp, 0, sizeof(dp));
            for (int i = 0; i <= lenS; ++i)
                dp[i][0] = 1;
            for (int i = 1; i <= lenS; ++i)
                for (int j = 1; j <= lenT && j <= i; ++j)
                {
                    if (i == j)
                        dp[i][j] = S.substr(0, i) == T.substr(0, j);
                    else
                        if (S[i - 1] != T[j - 1])
                            dp[i][j] = dp[i - 1][j];
                        else
                            dp[i][j] = dp[i - 1][j -1] + dp[i - 1][j];
                }
            return dp[lenS][lenT];
        }
    };

     如果,初始化用了memset了,那么if(i==j)语句就可以省略了

  • 相关阅读:
    Truck History(poj 1789)
    Highways poj 2485
    117. Populating Next Right Pointers in Each Node II
    116. Populating Next Right Pointers in Each Node
    115. Distinct Subsequences
    114. Flatten Binary Tree to Linked List
    113. Path Sum II
    109. Convert Sorted List to Binary Search Tree
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
  • 原文地址:https://www.cnblogs.com/higerzhang/p/4133793.html
Copyright © 2011-2022 走看看