【LeetCode 115 Distinct Subsequences】

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

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).

Example 1:

Input: S = "rabbbit", T = "rabbit"
Output: 3
Explanation:

As shown below, there are 3 ways you can generate "rabbit" from S.
(The caret symbol ^ means the chosen letters)

rabbbit
^^^^ ^^
rabbbit
^^ ^^^^
rabbbit
^^^ ^^^

Example 2:

Input: S = "babgbag", T = "bag"
Output: 5
Explanation:

As shown below, there are 5 ways you can generate "bag" from S.
(The caret symbol ^ means the chosen letters)

babgbag
^^ ^
babgbag
^^    ^
babgbag
^    ^^
babgbag
  ^  ^^
babgbag
    ^^^

Solution1:常规的递归思路(大规模时,会出现Runtime Error)

class Solution {
public:
    int count = 0;
    void findChar(string s, string t, int indexS, int indexT){
       for(int i = indexS; i < s.length(); i++){
           if(indexT != t.length()-1 && s[i] == t[indexT]){
               findChar(s, t, i+1, indexT+1);
           }
           else if(indexT == t.length()-1 && s[i] == t[indexT]){
               count++;
           }
           else
               ;
       }
       return ;
    }
    int numDistinct(string s, string t) {
        int lenS = s.length();
        int lenT = t.length();
        if(lenS != 0 && lenT != 0){
            findChar(s, t, 0, 0);
        }
        return count;
    }
};

Solution2:DP,并将边界情况即源串目标串为空串的情况也纳入考虑

递推关系的举例说明:

S:abb T:ab 则当源串指向最后一个b 目标串也匹配到最后一个b时,不同子串的总数量 = 去除当前字符的前缀源串中包含的去除当前被匹配字符的前缀目标串的数量 + 去除当前字符的前缀源串中已经包含的包括当前被匹配字符的目标串的数量,即ab中匹配a的数量为1,ab中匹配ab的数量为1,所以abb中匹配ab的数量为1+1 = 2

class Solution {
public:
    int numDistinct(string s, string t) {
        int m = s.length();
        int n = t.length();
        
        int dpSubseq[m+1][n+1];
        for(int i = 0; i <= m; i++){
            dpSubseq[i][0] = 1;
        }
        for(int j = 1; j <=n; j++){
            dpSubseq[0][j] = 0;
        }
        
        for(int j = 1; j <= n; j++){
            for(int i = 1; i <= m; i++){
                if(s[i-1] != t[j-1]){
                    dpSubseq[i][j] = dpSubseq[i-1][j];
                }else{
                    dpSubseq[i][j] = dpSubseq[i-1][j-1] + dpSubseq[i-1][j];
                }
            }
        }
        return dpSubseq[m][n];
    }
};

猜你喜欢

转载自blog.csdn.net/lqy0927/article/details/82085244