LeetCode #940 Distinct Subsequences II 不同的子序列 II 940 Distinct Subsequences II 不同的子序列 II

940 Distinct Subsequences II 不同的子序列 II

Description:
Given a string s, return the number of distinct non-empty subsequences of s. Since the answer may be very large, return it modulo 10^9 + 7.

A subsequence of a string is a new string that is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (i.e., "ace" is a subsequence of "abcde" while "aec" is not.

Example:

Example 1:

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

Example 2:

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

Example 3:

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

Constraints:

1 <= s.length <= 2000
s consists of lowercase English letters.

題目描述:
給定一個字符串 s,計算 s 的 不同非空子序列 的個數。因爲結果可能很大,所以返回答案需要對 10^9 + 7 取餘 。

字符串的 子序列 是經由原字符串刪除一些(也可能不刪除)字符但不改變剩餘字符相對位置的一個新字符串。

例如,"ace" 是 "abcde" 的一個子序列,但 "aec" 不是。

示例 :

示例 1:

輸入:s = "abc"
輸出:7
解釋:7 個不同的子序列分別是 "a", "b", "c", "ab", "ac", "bc", 以及 "abc"。

示例 2:

輸入:s = "aba"
輸出:6
解釋:6 個不同的子序列分別是 "a", "b", "ab", "ba", "aa" 以及 "aba"。

示例 3:

輸入:s = "aaa"
輸出:3
解釋:3 個不同的子序列分別是 "a", "aa" 以及 "aaa"。

提示:

1 <= s.length <= 2000
s 僅由小寫英文字母組成

思路:

動態規劃
設 dp[i] 表示 s[:i] 中非空子序列的個數
如果不考慮重複 dp[i] = dp[i - 1] + (dp[i - 1] + 1), 對每個字符都可以取或者不取, 取的時候會多出一個本身字符
考慮重複 dp[i] = dp[i - 1] + (dp[i - 1] - dp[pre[s[i]]), 前一部分表示不取當前字符, 那麼還是之前的值 dp[i - 1], 如果要取當前字符, 那麼前面的重複值需要被減去, 可以用一個 26 位的 count 數組記錄當前字符對應的 dp 的個數
因爲 dp 只與前一個狀態有關, 可以將空間複雜度優化爲 O(1)
時間複雜度爲 O(n), 空間複雜度爲 O(1)

代碼:
C++:

class Solution 
{
public:
    int distinctSubseqII(string s) 
    {
        vector<int> count(26);
        int result = 0, mod = 1e9 + 7, n = s.size(), pre = 0;
        for (int i = 0; i < n; i++) 
        {
            pre = result;
            result = ((result << 1) + 1L - count[s[i] - 'a'] + mod) % mod;
            count[s[i] - 'a'] = (pre + 1) % mod;
        }
        return result;
    }
};

Java:

class Solution {
    public int distinctSubseqII(String s) {
        long count[] = new long[26], result = 0, mod = 1_000_000_007, n = s.length(), pre = 0;
        for (int i = 0; i < n; i++) {
            pre = result;
            result = ((result << 1) + 1L - count[s.charAt(i) - 'a'] + mod) % mod;
            count[s.charAt(i) - 'a'] = (pre + 1) % mod;
        }
        return (int)result;
    }
}

Python:

class Solution:
    def distinctSubseqII(self, s: str) -> int:
        count, mod, result, n = [0] * 26, 10 ** 9 + 7, 0, len(s)
        for i in range(n):
            result, count[ord(s[i]) - ord('a')] = (result << 1) + 1 - count[ord(s[i]) - ord('a')], result + 1
        return result % mod
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章