1. 程式人生 > >DP動態規劃專題十一:LeetCode 115. Distinct Subsequences

DP動態規劃專題十一:LeetCode 115. Distinct Subsequences

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
    ^^^
假設dp[i][j]代表s.substring(i)和t.substring(j)的匹配的答案。這樣就有:
  1. 如果i和j處字元相同:dp[i][j] = dp[i+1][j] + dp[i+1][j+1];
  2. i和j處字元不相同:dp[i][j] = dp[i+1][j];
public int numDistinct(String s, String t) {
        int[][] dp = new int[s.length()][t.length()];
        return recursion(s, t, dp, 0, 0);
    }
    private int recursion(String s, String t, int[][] dp, int i, int j) {
        //base case
        int res = 0;
        if (j == t.length()) return 1;
        else if (i == s.length()) return 0;
        else if (dp[i][j] == -1) return 0;
        else if (dp[i][j] != 0) return dp[i][j];
        else {
            //recursion
            if (s.charAt(i) == t.charAt(j)) {
                res = recursion(s, t, dp, i+1, j+1) + recursion(s, t, dp, i+1, j);
            } else {
                res = recursion(s, t, dp, i+1, j);
            }
        }
        dp[i][j] = res == 0 ? -1 : res;
        return res;
    }