↓快轉到主要內容
  1. LeetCode/

LeetCode 940: Distinct Subsequences II

·1 分鐘· ·
LeetCode Hard Dynamic-Programming String
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: hard 第一次嘗試:2026-09-12

  • 提交紀錄:Accepted(一次通過)

解題思路
#

如果直接用「每個字元選或不選」,相同的子序列會被算很多次("aa" 選第一個 a 或第二個 a 都是 "a")。

依最後一個字元分類:end[c] = 以 c 結尾的不同子序列數。讀到新的字元 c 時:

  • 目前所有不同的子序列(sum(end.values()) 個),後面都可以接上 c,得到以 c 結尾的子序列。
  • 再加上單獨的 "c"。

這些新算出來的子序列,已經包含了所有舊的以 c 結尾的子序列(舊的是接在更早的子序列後面,那些更早的子序列現在也還在),所以直接覆蓋 end[c],不用加。

答案是 sum(end.values())。

我的解法
#

class Solution:
    def distinctSubseqII(self, s: str) -> int:
        MOD = 10 ** 9 + 7
        end = {}                                   # 以每個字元結尾的不同子序列數
        for c in s:
            end[c] = (sum(end.values()) + 1) % MOD # 全部接上 c,再加上 "c" 本身
        return sum(end.values()) % MOD

複雜度
#

時間 O(26 · n),空間 O(26)。

要特別避免的錯誤
#

  • end[c] 要覆蓋,不是累加:累加會重複算舊的以 c 結尾的子序列。
  • 題目要的是非空的子序列,不用加上空字串。

面試口說整理
#

我依最後一個字元把不同的子序列分類。讀到字元 c 時,目前所有不同的子序列後面接上 c,再加上 c 本身,就是以 c 結尾的所有不同子序列,而且已經包含舊的那些,所以直接覆蓋。最後把 26 個加起來。時間 O(26n)。

相關文章

LeetCode 1320: Minimum Distance to Type a Word Using Two Fingers
·1 分鐘
LeetCode Hard Dynamic-Programming State-Machine String
LeetCode 1320 解題筆記:打完 word[i] 時,一定有一根手指在 word[i] 上,狀態只要記另一根手指在哪;dp[other] 是另一根手指在 other 的最小距離
LeetCode 902: Numbers At Most N Given Digit Set
·1 分鐘
LeetCode Hard Dynamic-Programming Digit-Dp Math Binary-Search String
LeetCode 902 解題筆記:數位 DP,狀態是 (pos, tight, started);還沒開始時可以跳過這一位,代表位數比 n 少的數
LeetCode 1147: Longest Chunked Palindrome Decomposition
·1 分鐘
LeetCode Hard Dynamic-Programming Greedy Two-Pointers Rolling-Hash String
LeetCode 1147 解題筆記:從兩端同時往內累積字串,左右一相等就切成一對;越早切越好,剩下的中間(如果有)算一塊
LeetCode 488: Zuma Game
·2 分鐘
LeetCode Hard Dynamic-Programming Memoization Breadth-First-Search String Stack
LeetCode 488 解題筆記:board 最多 16 顆、hand 最多 5 顆,把 (board, hand) 整個當狀態做 DFS + 記憶化;只在「同色球前面」和「拆開兩顆同色球」兩種位置插入
LeetCode 1745: Palindrome Partitioning IV
·1 分鐘
LeetCode Hard Dynamic-Programming Interval-Dp String
LeetCode 1745 解題筆記:先用區間 DP 建好 is_pal[i][j],再枚舉兩個切點,三段都是回文就成立,O(n^2)
LeetCode 1092: Shortest Common Supersequence
·4 分鐘
LeetCode Hard Dynamic-Programming String
LeetCode 1092 解題筆記,依照原始 learning note 重新整理