115. Distinct Subsequences

问题

给定字符串S和字符串T,在S的子序列中,和T相同的有多少个。

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

思路

用dp[i][j]表示T[:i]和S[:j]之间的解。

如果T[i-1] != S[j-1],那么dp[i][j] = dp[i][j-1],因为末尾的字符不相等,不可能产生新的子串。

如果T[i-1] == S[j-1],当末尾字符相同时,先考虑S[:j-1]中本身有多少个子序列T[:i],有dp[i][j-1]个这样的序列。

然后考虑S[:j-1]中有多少个前缀子序列T[:i-1],这些子序列配上S[i-1](也是T[i-1])可以形成子序列T[:i],有dp[i-1][j-1]个这样的序列T[:i]。

所以此时dp[i][j] = dp[i][j-1] + dp[i-1][j-1]。

dp矩阵可以优化成数组,这里不多解释了,和之前 486. Predict the Winner 给出的三个gif图是一样的道理。

时间复杂度O(n*m),空间复杂度O(n*m)

代码

class Solution(object):
    def numDistinct(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: int
        """
        if(len(t) == 0 or len(s) == 0 or len(t) > len(s)):
            return 0
        dp = [ [0 for _ in range(len(s)+1)] for _ in range(len(t)+1)]
        for j in range(len(s)+1):
            dp[0][j]=1

        for i in range(1,len(t)+1):
            for j in range(i,len(s)+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]
        return dp[len(t)][len(s)]

类似题目

392. Is Subsequence

posted @ 2018-10-11 23:34  PilgrimHui  阅读(257)  评论(0编辑  收藏  举报