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

LeetCode 2537: Count the Number of Good Subarrays

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

基本資料
#

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

  • 提交紀錄:Wrong Answer ×2 → Accepted ×2

解題思路
#

視窗裡相同值的 pair 數:加入一個 x 時,它可以跟視窗裡原本的每個 x 配對,pair 數增加 cnt[x](加入前的數量)。移出時反過來,減少 cnt[x] - 1(移出後的數量)。

pair 數只會隨視窗變大而增加,「至少 k 對」是單調的,用「至少」型的計數:合法時一直縮左邊,count += left。

我的嘗試
#

我一開始用組合數 C(cnt, 2) 算:加入時扣掉舊的 C(cnt - 1, 2)、加上新的 C(cnt, 2)。

版本問題
第一版組合數裡用了 freq[nums[right - 1]](前一個元素的數量),應該是 freq[nums[right]]。例如 nums = [2, 2, 3]、k = 1:答案是 2,回傳 4
第二版修好 index,但縮左邊時只更新了 pair 數,沒有把 freq[nums[left]] 減一。例如 nums = [3, 2, 2, 3]、k = 1:答案是 4,回傳 5
第三版 AC補上 freq[nums[left]] -= 1
第四版 AC改成「加入時加 cnt[x]、移出時減 cnt[x]」,簡單很多

正確解法
#

class Solution:
    def countGood(self, nums: List[int], k: int) -> int:
        cnt = Counter()
        pairs = left = count = 0
        for x in nums:
            pairs += cnt[x]                        # 跟視窗裡每個 x 配一對
            cnt[x] += 1
            while pairs >= k:
                y = nums[left]
                cnt[y] -= 1
                pairs -= cnt[y]                    # 少了跟剩下的 y 配的那些對
                left += 1
            count += left
        return count

複雜度
#

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

要特別避免的錯誤
#

  • 縮視窗時只更新統計值,忘了更新計數表。
  • 增量更新時用錯元素(nums[right - 1] vs nums[right])。

面試口說整理
#

加入一個 x 時,它跟視窗裡原本的每個 x 都能配成一對,所以 pair 數加上原本的數量;移出時反過來。pair 數隨視窗變大只增不減,所以用「至少」型的滑動視窗:至少 k 對時一直縮左邊,左端在 0 到 left - 1 都合法,加上 left。時間 O(n)。

相關文章

LeetCode 2875: Minimum Size Subarray in Infinite Array
·1 分鐘
LeetCode Medium Sliding-Window Prefix-Sum Hash-Table Array
LeetCode 2875 解題筆記:先拿掉 target // sum 個完整週期,剩下的餘數比一整圈小,一定能在兩份 nums 接起來的陣列裡用滑動視窗找到
LeetCode 2831: Find the Longest Equal Subarray
·1 分鐘
LeetCode Medium Sliding-Window Hash-Table Binary-Search Array
LeetCode 2831 解題筆記:對每個值,把它出現的位置列出來;在位置列表上滑動視窗,要刪的數量 = 位置跨度 − 這個值的個數
LeetCode 3795: Minimum Subarray Length With Distinct Sum At Least K
·1 分鐘
LeetCode Medium Sliding-Window Hash-Table Array
LeetCode 3795 解題筆記:求最短的可變視窗;同一個值只算一次,記錄每個值最後出現的位置,左邊界移出的是最後一次出現才扣掉
LeetCode 3679: Minimum Discards to Balance Inventory
·1 分鐘
LeetCode Medium Sliding-Window Hash-Table Simulation Counting Array
LeetCode 3679 解題筆記:規則已經決定哪些要丟,直接模擬;長度 w 的視窗只計算「留下來」的到貨,被丟掉的離開視窗時不能再扣
LeetCode 2841: Maximum Sum of Almost Unique Subarray
·1 分鐘
LeetCode Medium Sliding-Window Hash-Table Array
LeetCode 2841 解題筆記:固定長度 k 的視窗,維護總和與計數雜湊表;不同值的個數就是雜湊表的大小,數量歸零要刪 key
LeetCode 1248: Count Number of Nice Subarrays
·2 分鐘
LeetCode Medium Sliding-Window Prefix-Sum Hash-Table Array
LeetCode 1248 解題筆記:「剛好 k 個奇數」不單調,改成「最多 k 個」減「最多 k - 1 個」;或用前綴和 + 雜湊表