Skip to content

Latest commit

 

History

History
155 lines (92 loc) · 3 KB

0940._Distinct_Subsequences_II.md

File metadata and controls

155 lines (92 loc) · 3 KB

940. Distinct Subsequences II

难度: Hard

刷题内容

原题连接

内容描述

Given a string S, count the number of distinct, non-empty subsequences of S .

Since the result may be large, return the answer modulo 10^9 + 7.

 

Example 1:

Input: "abc"
Output: 7
Explanation: The 7 distinct subsequences are "a", "b", "c", "ab", "ac", "bc", and "abc".
Example 2:

Input: "aba"
Output: 6
Explanation: The 6 distinct subsequences are "a", "b", "ab", "ba", "aa" and "aba".
Example 3:

Input: "aaa"
Output: 3
Explanation: The 3 distinct subsequences are "a", "aa" and "aaa".
 

 

Note:

S contains only lowercase letters.
1 <= S.length <= 2000

解题方案

思路 1 - 时间复杂度: O(N)- 空间复杂度: O(N)******

DP

dp[i]代表以S[i-1]为结尾的distinct subsequence的个数

dp[0] = 1,因为一个字符都没有只能是空字符串

如果当前字符s[i-1]之前没有出现过,那么自然我们的d[i] = 2 * dp[i-1]

我们可以用字典存一下之前出现过的字符

beats 100%

class Solution:
    def distinctSubseqII(self, S):
        """
        :type S: str
        :rtype: int
        """
        lookup = {}
        dp = [0] * (len(S)+1)
        dp[0] = 1
        for i in range(1, len(S)+1):
            dp[i] = 2 * dp[i-1]
            if S[i-1] in lookup:
                dp[i] = dp[i] - dp[lookup[S[i-1]]]
            lookup[S[i-1]] = i-1
        return (dp[-1]-1) % (10**9 + 7)

思路 2 - 时间复杂度: O(N)- 空间复杂度: O(1)******

endWith某个字符的思路,见lee215

假设当前有N个不同的seq,每个seq加上一个新的字母,又是新的N个不同sequence了。
但新的seq中,有一部分原来就有。
比如新的字母是'a',那么原来以'a'结尾的seq,每一个都会存在新的这N个seq中。

到这里,解题思路就比较清楚了。
我们需要用一个数组int endsWith[26],
endsWith[i]来表示以第i个字母结束的sequence数量。

最后修饰一下代码细节。

数组全部初始化为0。
正好按照题目要求,空string不计作subseq。
每次更新的时候,end[i] = sum(end) + 1。
加1的原因是,比如我们遇到新字母'a',新的N个seq里不包含“a”本身这种情况,需要额外加上。
class Solution:
    def distinctSubseqII(self, S):
        """
        :type S: str
        :rtype: int
        """
        end = [0] * 26
        for c in S:
            end[ord(c) - ord('a')] = sum(end) + 1
        return sum(end) % (10**9 + 7)

还可以用一个变量保存当前数组和,避免重复计算。

class Solution:
    def distinctSubseqII(self, S):
        """
        :type S: str
        :rtype: int
        """
        res, end = 0, {}
        for c in S:
            res, end[c] = res * 2 + 1 - end.get(c, 0), res + 1
        return res % (10**9 + 7)