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

Here is an example:
S = “rabbbit”, T = “rabbit”
Return 3.

题意:有两个字符串S和T,求S中有多少个子字符串和T相等。

思路:
可以暴力的枚举S的所有子串然后和T比较,时间复杂度将会是S长度的阶乘。

动态规划的方法,用dp[i][j]表示S从0到j有多少个子串和T从0到i相等。
举个栗子:S是abb,T是ab,下面用一个矩阵表示
T/S 空 a b b
空 1 1 1 1
a 0 1 1 1
b 0 0 1 2
当T是空串的时候,S任意的前缀串都有空串和T相等,所以第一行都是1.
当Si和Tj字符不等时,我们只能看S的0到j-1和T有多少个匹配,即dp[i][j] = dp[i][j-1];
当Si和Tj字符相等时,假设是例子中最后ab和abb的情况:
第一个角度是可以把最后的两个b看作是一起后加上去的,那么ab和abb的匹配数等于a和ab的匹配数,即dp[i][j] += dp[i-1][j-1];
第二个角度是可以把abb最后一个b视作替换掉它之前的b,那么ab和abb的匹配数等于ab和ab的匹配树,即dp[i][j] += dp[i][j-1]。
所以dp[i][j] = dp[i-1][j-1] + dp[i][j-1]。

public int numDistinct(String s, String t) {
    if (s == null) {
        return 0;
    }
    if (t == null) {
        return 1;
    }

    int slen = s.length();
    int tlen = t.length();
    int[][] dp = new int[tlen][slen];

    for (int i = 0; i <= slen; i++) {
        dp[0][i] = 1;
    }

    for (int i = 1; i <= tlen; i++) {
        for (int j = 1; j <= slen; j++) {
            if (s.charAt(j) == t.charAt(i)) {
                dp[i][j] = dp[i-1][j-1] + dp[i][j-1];
            } else {
                dp[i][j] = dp[i][j-1];
            }
        }
    }

    return dp[tlen][slen];
}
    原文作者:ShutLove
    原文地址: https://www.jianshu.com/p/8cb6d6830a04
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞