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

LeetCode 2009: Minimum Number of Operations to Make Array Continuous

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

基本資料
#

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

  • 提交紀錄:TLE → WA → RE → AC → WA → AC

解題思路
#

最後的陣列是 [x, x + 1, ..., x + n - 1]。原本的數如果落在這個範圍裡、而且不重複,就可以保留,其他都要改。

所以要找:哪個長度 n 的值域區間 [x, x + n - 1] 裡,原本的不同值最多。

  1. 去重後排序。
  2. 滑動視窗:右端是 vals[right],左端縮到 vals[right] - vals[left] <= n - 1。視窗裡的值都能留。
  3. 答案是 n - 最多能留的數量。

區間的左端可以假設就是某個原本的值(往右推到第一個原本的值不會變差),所以只要以每個 vals[left] 當起點。

我的嘗試
#

版本問題
第一版 TLE在整個值域 0..max 上滑動,還用 in nums(list)檢查,值可以到 10^9
第二版 WA改成在排序後的陣列上滑動,但沒去重,重複的值也被算成「可以保留」。例如 [1, 1]:其中一個要改成 2,答案是 1,回傳 0
第三版 RE加上重複計數,但變數名稱打錯(deplicate)
第四版 AC修好拼字,用 duplicate 扣掉視窗內的重複
第五版 WA想簡化又把去重拿掉了
第六版 AC直接 sorted(set(nums)),最乾淨

正確解法
#

class Solution:
    def minOperations(self, nums: List[int]) -> int:
        n = len(nums)
        vals = sorted(set(nums))                   # 重複的值只能留一個
        left = best = 0
        for right, x in enumerate(vals):
            while x - vals[left] > n - 1:
                left += 1
            best = max(best, right - left + 1)     # 這些值都能留
        return n - best

注意視窗寬度用的是原本的 n,不是去重後的長度。

複雜度
#

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

要特別避免的錯誤
#

  • 沒去重:重複的值只能留一個。
  • 視窗寬度用了去重後的長度:最後的陣列長度還是原本的 n。

面試口說整理
#

最後是長度 n 的連續整數,原本落在範圍裡而且不重複的值都能留下。所以我先去重排序,用滑動視窗找最大值減最小值不超過 n - 1 的最多個值,答案是 n 減掉它。寬度要用原本的 n。時間 O(n log n)。

相關文章

LeetCode 2106: Maximum Fruits Harvested After at Most K Steps
·1 分鐘
LeetCode Hard Sliding-Window Prefix-Sum Binary-Search Array
LeetCode 2106 解題筆記:採到的一定是連續一段水果;走完 [L, R] 的最少步數是 (R - L) + min(|start - L|, |R - start|),在水果陣列上用滑動視窗
LeetCode 2831: Find the Longest Equal Subarray
·1 分鐘
LeetCode Medium Sliding-Window Hash-Table Binary-Search Array
LeetCode 2831 解題筆記:對每個值,把它出現的位置列出來;在位置列表上滑動視窗,要刪的數量 = 位置跨度 − 這個值的個數
LeetCode 2781: Length of the Longest Valid Substring
·2 分鐘
LeetCode Hard Sliding-Window Hash-Table String Trie
LeetCode 2781 解題筆記:禁字最長只有 10,每個右端只檢查最後 10 個字元組成的後綴;找到禁字就把左端推到它後面,要找最短的那個(最靠右的起點)
LeetCode 2779: Maximum Beauty of an Array After Applying Operation
·1 分鐘
LeetCode Medium Sliding-Window Sorting Binary-Search Array
LeetCode 2779 解題筆記:每個數可以變成 [x - k, x + k] 裡的任何值,一群數能變成同一個值 ⇔ 最大 - 最小 <= 2k;排序後找最長的這種視窗
LeetCode 220: Contains Duplicate III
·2 分鐘
LeetCode Hard Sliding-Window Bucket-Sort Ordered-Set Sorting Array
LeetCode 220 解題筆記:桶大小設成 valueDiff + 1,同一個桶裡的兩個數一定符合;只要再看相鄰兩個桶。視窗只保留最近 indexDiff 個數,所以每個桶最多一個數
LeetCode 2953: Count Complete Substrings
·2 分鐘
LeetCode Hard Sliding-Window Hash-Table String
LeetCode 2953 解題筆記:先在相鄰字元差 > 2 的地方切段;每段枚舉有幾種字元 d,視窗長度固定是 d × k,維護「剛好出現 k 次的字元數」