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

LeetCode 135: Candy

·1 分鐘· ·
LeetCode Hard Greedy Array
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: hard 第一次嘗試:2025-08-05

  • 提交紀錄:Runtime Error ×3 → Accepted ×2 → Time Limit Exceeded → Accepted

解題思路
#

每個人的條件同時跟左右鄰居有關,分開處理(Greedy 模板三):

  • left[i]:只看左邊。分數比左邊高就是 left[i - 1] + 1,否則 1。
  • right[i]:只看右邊,從右往左算。
  • 每個人拿 max(left[i], right[i])。

兩個值都是必要的下界:往左一路遞增的長度決定了至少要幾顆,往右也一樣,所以取較大值就是最少的。

我的嘗試
#

我一開始用分治:找區間內分數最高的人,先遞迴處理左右兩半,再讓他比較低的鄰居多 1 顆。

版本問題
前兩次 RE用 ratings.index(max(ratings[left:right])) 在整個陣列找最大值的位置,找到的可能在區間外。[2, 2] 給了 3 顆(答案 2),[4, 1, 2] 無限遞迴
第三次 RE改成在切片裡找,但右半邊的條件寫成 max_index < n - 1,最大值在區間最右邊時會遞迴到空區間,max() 對空序列報錯,例如 [0, 2, 4]
兩次 AC條件改成 max_index < right - 1,但跑了 6.5 秒:分數遞增時每層只少一個,O(n²)
TLE把內建的 max / index 換成自己的 for 迴圈,演算法一樣是 O(n²),Python 迴圈更慢

正確解法
#

class Solution:
    def candy(self, ratings: List[int]) -> int:
        n = len(ratings)
        left = [1] * n
        for i in range(1, n):
            if ratings[i] > ratings[i - 1]:
                left[i] = left[i - 1] + 1
        right = [1] * n
        for i in range(n - 2, -1, -1):
            if ratings[i] > ratings[i + 1]:
                right[i] = right[i + 1] + 1
        return sum(max(a, b) for a, b in zip(left, right))

複雜度
#

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

要特別避免的錯誤
#

  • 遞迴處理子區間時,位置要在子區間裡找,不是整個陣列。
  • 遞迴的邊界要用子區間的右端,不是整個陣列的右端。
  • 每層找最大值再分治,遇到單調的輸入會退化成 O(n²)。

面試口說整理
#

條件跟左右兩邊都有關,所以我分兩次掃:左往右時,比左邊高就比左邊多 1;右往左時,比右邊高就比右邊多 1。每個人取兩者較大值,因為兩個都是必要的下界。時間 O(n)。

相關文章

LeetCode 3638: Maximum Balanced Shipments
·1 分鐘
LeetCode Medium Dynamic-Programming Greedy Monotonic-Stack Array
LeetCode 3638 解題筆記:貪心,一段一旦出現比這段最大值小的數就馬上切;因為切之前的那段是非遞減的,最大值就是前一個數
LeetCode 3627: Maximum Median Sum of Subsequences of Size 3
·1 分鐘
LeetCode Medium Math Greedy Sorting Game-Theory Array
LeetCode 3627 解題筆記:排序後每次拿最大的兩個和最小的一個,中位數是第二大的;答案是從尾端往前每隔一個取,共 n / 3 個
LeetCode 927: Three Equal Parts
·2 分鐘
LeetCode Hard Math Array
LeetCode 927 解題筆記:三段的 1 一樣多,先數 1;第三段一定延伸到陣列尾端,它的長度決定每段要比對的內容,再檢查三段的位置不重疊
LeetCode 952: Largest Component Size by Common Factor
·2 分鐘
LeetCode Hard Math Number-Theory Union-Find Hash-Table Array
LeetCode 952 解題筆記:有共同因數 ⇔ 有共同的質因數;把每個數分解質因數,同一個質因數的 index 用 Union-Find 合併,不用兩兩算 GCD
LeetCode 3487: Maximum Unique Subarray Sum After Deletion
·1 分鐘
LeetCode Easy Greedy Hash-Table Array
LeetCode 3487 解題筆記:可以任意刪除,所以等於挑不重複的值;非負的全拿,全是負數時只拿最大的一個
LeetCode 3074: Apple Redistribution into Boxes
·1 分鐘
LeetCode Easy Array Greedy Sorting
LeetCode 3074 解題筆記:箱子可以隨便分,所以從容量最大的箱子開始拿,總容量夠裝所有蘋果就停