[leetcode115]Distinct Subsequences解题报告

115. Distinct Subsequences

代码即解题思路github地址
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
^^^

解题思路1:深度优先搜索
逐个比较s中的字符是否和t的首字母相等,如果相等,假设s[i] = t[0],则递归求s[i+1:]中有多少个不同的子序列等于t[1:],直至t为空或者s的长度小于t的长度。

class Solution:
    def numDistinct(self, s, t):
        if len(t) == 0:
            return 1
        if len(s) < len(t):
            return 0
        total = 0
        for i, si in enumerate(s):
            if si == t[0]:
                total += self.numDistinct2(s[i + 1:], t[1:])
        return total

这种算法复杂度很高,最坏情况下s与t分别为m、n(m>n)个相同字符c,则复杂度为 Cnm C m n

结题思路2:动态规划法
用dp[i][j]表示s[:i]中子序列等于t[:j]的数目,如果s[i]和t[j]不想等,s[:i]中子序列等t[:j]的数目的数目应该是s[:i-1]中
子序列等于t[:j]的数目;若相等,则s[:i]中子序列等t[:j]的数目的数目应该是s[:i-1]中子序列等于t[:j-1]的子序列数据与
s[:i-1]中子序列等于t[:j]之和。递推公式如下:

  1. 如果s[i] == t[j],则dp[i][j] = dp[i-1][j-1] + dp[i-1][j]
  2. 如果s[i] != t[j],则dp[i][j] = dp[i-1][j]

通过观察递推公式可知,dp[i][j]仅和dp[i-1][j]和dp[i-1][j]有关,因此可以用一维数组代替矩阵。
然后考虑边界条件,如果t为空,则空时任何集合的子集,总数为1。如果s为空,则t不为空时,总数为零。如果将s和t第0位补上”“,则

dp[0][0] = 1
dp[0][1:] = 0
dp[:][0] = 1

s\t“”rabbit
“”1000000
r110000
a1110000
b1111000
b1112100
b1113300
i1113330
t1113333
class Solution:
    def numDistinct(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: int
        """
        dp = [0] * (len(t) + 1)
        dp[0] = 1
        for i in range(len(s)):
            before = 1
            for j in range(min(i + 1, len(t))):
                tmp = dp[j + 1]
                if s[i] == t[j]:
                    dp[j + 1] = dp[j + 1] + before
                before = tmp
        return dp[-1]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值