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

LeetCode 3795: Minimum Subarray Length With Distinct Sum At Least K

·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-03

  • 提交紀錄:Wrong Answer → Accepted

解題思路
#

所有值都是正的,視窗變大時「不同值的和」只會變大或不變,所以可以用「求最短」的可變視窗:合法時更新答案,再試著縮左邊。

難點是同一個值在視窗裡出現多次只算一次:

  • 用 last[x] 記錄值 x 在視窗裡最後一次出現的位置。加入 x 時,x 不在 last 裡才把它加進總和。
  • 左邊界移出 nums[left] 時,只有 last[nums[left]] == left(它是視窗裡最後一個 nums[left])才扣掉並刪除;否則右邊還有同樣的值,總和不變。

我的嘗試
#

第一版直接用一般的總和,沒處理重複。例如 nums = [4, 4]、k = 7:不同值的和最多只有 4,答案是 -1;這版把兩個 4 加起來是 8,回傳 2。

正確解法
#

class Solution:
    def minLength(self, nums: List[int], k: int) -> int:
        last = {}                                  # 值 -> 視窗內最後出現的位置
        total = left = 0
        best = float("inf")
        for right, x in enumerate(nums):
            if x not in last:
                total += x
            last[x] = right
            while total >= k:
                best = min(best, right - left + 1)
                if last[nums[left]] == left:       # 視窗裡沒有其他的 nums[left]
                    total -= nums[left]
                    del last[nums[left]]
                left += 1
        return best if best < float("inf") else -1

複雜度
#

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

要特別避免的錯誤
#

  • 用一般的總和:重複的值會被算很多次。
  • 移出左邊的值時,右邊可能還有同一個值,不能直接扣掉。

面試口說整理
#

值都是正的,視窗越大不同值的和越大,所以用「求最短」的滑動視窗。重複的值只算一次:我記錄每個值在視窗裡最後出現的位置,加入時第一次出現才加進總和;左邊移出時,只有它是視窗裡最後一個同樣的值才扣掉。時間 O(n)。

相關文章

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 個」;或用前綴和 + 雜湊表
LeetCode 2653: Sliding Subarray Beauty
·1 分鐘
LeetCode Medium Sliding-Window Hash-Table Array
LeetCode 2653 解題筆記:值域只有 -50 到 50,固定視窗用計數陣列維護,每個視窗從 -50 往上累加找第 x 小的負數
LeetCode 2461: Maximum Sum of Distinct Subarrays With Length K
·1 分鐘
LeetCode Medium Sliding-Window Hash-Table Array
LeetCode 2461 解題筆記:固定長度 k 的視窗,不同值的個數剛好等於 k 才代表全部不重複
LeetCode 3694: Distinct Points Reachable After Substring Removal
·1 分鐘
LeetCode Medium Sliding-Window Prefix-Sum Hash-Table String
LeetCode 3694 解題筆記:終點 = 全部的位移 − 被刪掉那段的位移;用長度 k 的視窗維護那段的位移,把每個終點放進 set