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

LeetCode 2875: Minimum Size Subarray in Infinite Array

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

基本資料
#

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

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

解題思路
#

設 total = sum(nums)、full, rest = divmod(target, total)。

  • 長度至少 n 的子陣列一定包含一整圈(總和 total),把它拿掉,剩下的還是無限陣列裡的一段連續子陣列。所以答案 = full × n + 總和剛好是 rest 的最短子陣列。
  • rest < total,數字都是正的,那段子陣列長度一定 < n,最多橫跨兩份 nums,在 nums + nums 上用滑動視窗找就夠了。
  • rest == 0 時答案就是 full × n。

我的嘗試
#

版本問題
第一版把 target 換成 target % sum 後,忘了把完整的週期加回去。例如 nums = [1]、target = 6:答案是 6,回傳 0
第二版加回 n * divisor,但 sum 是在 nums 已經接成兩份之後才算的,總和多了一倍。例如 nums = [1, 4, 2]、target = 24:答案是 11,回傳 -1
AC先算原本的總和和週期數,再把 nums 接成兩份

正確解法
#

class Solution:
    def minSizeSubarray(self, nums: List[int], target: int) -> int:
        n = len(nums)
        full, rest = divmod(target, sum(nums))     # 用原本的總和
        if rest == 0:
            return full * n

        arr = nums + nums                          # 餘數那段最多跨兩份
        left = window = 0
        best = float("inf")
        for right, x in enumerate(arr):
            window += x
            while window > rest:
                window -= arr[left]
                left += 1
            if window == rest:
                best = min(best, right - left + 1)
        return -1 if best == float("inf") else full * n + best

複雜度
#

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

要特別避免的錯誤
#

  • 只處理餘數,忘了加回完整週期。
  • 先把陣列接成兩份再算總和:總和多一倍。

面試口說整理
#

很長的子陣列一定包含完整的週期,所以我先用 target 除以總和拿掉完整週期,每個週期是 n 個元素。剩下的餘數比一整圈小,數字都是正的,那段一定在兩份 nums 接起來的範圍內,用滑動視窗找總和剛好等於餘數的最短一段。時間 O(n)。

相關文章

LeetCode 1248: Count Number of Nice Subarrays
·2 分鐘
LeetCode Medium Sliding-Window Prefix-Sum Hash-Table Array
LeetCode 1248 解題筆記:「剛好 k 個奇數」不單調,改成「最多 k 個」減「最多 k - 1 個」;或用前綴和 + 雜湊表
LeetCode 3413: Maximum Coins From K Consecutive Bags
·2 分鐘
LeetCode Medium Sliding-Window Greedy Sorting Prefix-Sum Binary-Search Array
LeetCode 3413 解題筆記:最佳的 k 個袋子,一定有一端對齊某段的端點;分別算「左端對齊段的起點」和「右端對齊段的終點」(鏡像後重用同一個函式)
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 3694: Distinct Points Reachable After Substring Removal
·1 分鐘
LeetCode Medium Sliding-Window Prefix-Sum Hash-Table String
LeetCode 3694 解題筆記:終點 = 全部的位移 − 被刪掉那段的位移;用長度 k 的視窗維護那段的位移,把每個終點放進 set
LeetCode 3679: Minimum Discards to Balance Inventory
·1 分鐘
LeetCode Medium Sliding-Window Hash-Table Simulation Counting Array
LeetCode 3679 解題筆記:規則已經決定哪些要丟,直接模擬;長度 w 的視窗只計算「留下來」的到貨,被丟掉的離開視窗時不能再扣