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

LeetCode 3298: Count Substrings That Can Be Rearranged to Contain a String II

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

基本資料
#

難易度: hard 第一次嘗試:2026-01-20

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

解題思路
#

子字串能重排成以 word2 開頭 ⇔ 它的每個字元數量都 >= word2 的數量。條件單調,用「至少」型的計數:

  • need = Counter(word2),meet = 數量已經達標的字元種類數。
  • 加入字元時,數量剛好變成 need[c] 就 meet += 1。
  • meet == len(need) 時一直縮左邊;移出時數量從 need[c] 掉到 need[c] - 1 就 meet -= 1。
  • count += left。

題目要求線性時間,每次只更新一個字元,meet 讓檢查是 O(1),不用每次比較整個計數表。

我的解法
#

class Solution:
    def validSubstringCount(self, word1: str, word2: str) -> int:
        need = Counter(word2)
        have = Counter()
        meet = left = count = 0
        for c in word1:
            have[c] += 1
            if have[c] == need[c]:
                meet += 1
            while meet == len(need):
                d = word1[left]
                if have[d] == need[d]:
                    meet -= 1                      # 移出後就不夠了
                have[d] -= 1
                left += 1
            count += left
        return count

不在 word2 裡的字元 need[c] = 0:have[c] 從 0 加到 1 不會等於 0,所以不會影響 meet;移出時 have[d] 是 >= 1 也不等於 0。

複雜度
#

時間 O(n + m),空間 O(26)。

要特別避免的錯誤
#

  • 每次都比較整個計數表:常數大,這題記憶體和時間都卡比較緊。
  • 用 Counter 查不在 word2 的字元時,need[c] 是 0,要確認 meet 不會被誤加。

面試口說整理
#

能重排成以 word2 開頭,代表每個字元的數量都不少於 word2,這是單調的。我用「至少」型的滑動視窗,meet 記錄有幾種字元已經達標,全部達標時一直縮左邊,縮到少一種,左端在 0 到 left - 1 都合法,加上 left。時間 O(n + m)。

相關文章

LeetCode 2781: Length of the Longest Valid Substring
·2 分鐘
LeetCode Hard Sliding-Window Hash-Table String Trie
LeetCode 2781 解題筆記:禁字最長只有 10,每個右端只檢查最後 10 個字元組成的後綴;找到禁字就把左端推到它後面,要找最短的那個(最靠右的起點)
LeetCode 2953: Count Complete Substrings
·2 分鐘
LeetCode Hard Sliding-Window Hash-Table String
LeetCode 2953 解題筆記:先在相鄰字元差 > 2 的地方切段;每段枚舉有幾種字元 d,視窗長度固定是 d × k,維護「剛好出現 k 次的字元數」
LeetCode 3090: Maximum Length Substring With Two Occurrences
·1 分鐘
LeetCode Easy Sliding-Window Hash-Table String
LeetCode 3090 解題筆記:「求最長」的滑動視窗,剛加進來的字元超過 2 次就縮左邊
LeetCode 1358: Number of Substrings Containing All Three Characters
·1 分鐘
LeetCode Medium Sliding-Window Hash-Table String
LeetCode 1358 解題筆記:「至少各一個 a、b、c」的計數視窗:三種都有時一直縮左邊,count += left
LeetCode 3325: Count Substrings With K-Frequency Characters I
·1 分鐘
LeetCode Medium Sliding-Window Hash-Table String
LeetCode 3325 解題筆記:「至少一個字元出現 k 次」的計數視窗;剛加入的字元湊滿 k 次就一直縮,縮到它變成 k - 1 次為止
LeetCode 1763: Longest Nice Substring
·1 分鐘
LeetCode Easy Sliding-Window Divide-and-Conquer Hash-Table String Bit-Manipulation
LeetCode 1763 解題筆記:沒有大小寫配對的字元一定不在答案裡,用它切開字串遞迴;長度相同時取左邊的