【LeetCode] 115の異なる配列

トピックへのリンク:https://leetcode-cn.com/problems/distinct-subsequences/

件名の説明:

文字列と文字列S 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
    ^^^

アイデア:

ダイナミックプログラミング

dp[i][j]代表Tの前にi文字列を作ることができるS前に、j文字列の最大数。

だから、運動方程式:

場合はS[j] == T[i]dp[i][j] = dp[i-1][j-1] + dp[i][j-1];

場合にはS[j] != T[i]dp[i][j] = dp[i][j-1]

例えば、一例のように

最初のラインについては、T空のセットは、すべての文字列のサブセットであるため、それは、空であるので、我々は最初の行です1

最初の列のため、S組成ように、空であるT数は勿論です0

どのように以下のためとして、私たちは自分自身でそれをシミュレートし、運動方程式をすることによってすることができます!

コード:

class Solution:
    def numDistinct(self, s: str, t: str) -> int:
        n1 = len(s)
        n2 = len(t)
        dp = [[0] * (n1 + 1) for _ in range(n2 + 1)]
        for j in range(n1 + 1):
            dp[0][j] = 1
        for i in range(1, n2 + 1):
            for j in range(1, n1 + 1):
                if t[i - 1] == s[j - 1]:
                    dp[i][j] = dp[i - 1][j - 1]  + dp[i][j - 1]
                else:
                    dp[i][j] = dp[i][j - 1]
        #print(dp)
        return dp[-1][-1]

ジャワ

class Solution {
    public int numDistinct(String s, String t) {
        int[][] dp = new int[t.length() + 1][s.length() + 1];
        for (int j = 0; j < s.length() + 1; j++) dp[0][j] = 1;
        for (int i = 1; i < t.length() + 1; i++) {
            for (int j = 1; j < s.length() + 1; j++) {
                if (t.charAt(i - 1) == s.charAt(j - 1)) dp[i][j] = dp[i - 1][j - 1] + dp[i][j - 1];
                else dp[i][j] = dp[i][j - 1];
            }
        }
        return dp[t.length()][s.length()];
    }
}

おすすめ

転載: www.cnblogs.com/powercai/p/11116692.html