1. 程式人生 > >【LeetCode】130.Distinct Subsequences

【LeetCode】130.Distinct Subsequences

題目描述(Hard)

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

題目連結

https://leetcode.com/problems/distinct-subsequences/description/

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
    ^^^

演算法分析

參考[LeetCode] Distinct Subsequences 不同的子序列,如果S[i]==T[j],那麼dp[i][j] = dp[i-1][j-1] + dp[i-1][j]。意思是:如果當前S[i]==T[j],那麼當前這個字母即可以保留也可以拋棄,所以變換方法等於保留這個字母的變換方法加上不用這個字母的變換方法。如果S[i]!=T[i],那麼dp[i][j] = dp[i-1][j],意思是如果當前字元不等,那麼就只能拋棄當前這個字元。

提交程式碼:

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