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

LeetCode 1353: Maximum Number of Events That Can Be Attended

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

基本資料
#

難易度: medium 第一次嘗試:2025-07-07

  • 提交紀錄:Wrong Answer → Accepted → Accepted(整理過一次)

解題思路
#

每個活動可以在 [start, end] 之間任選一天參加,一天只能參加一個。

貪心:每天在「已經開始、還沒結束」的活動裡,參加最早結束的那個。 晚結束的活動之後還有機會,早結束的錯過就沒了。

做法:

  1. 依開始日排序。
  2. 用 min-heap 存「已經開始的活動的結束日」。
  3. 每天先把今天開始的活動推進 heap,丟掉已經過期的,再參加堆頂那個。

我的第一版:一天對應一個活動
#

events.sort(key=lambda x: x[0])
for s, e in events:
    if time >= s and time <= e:
        res += 1
    time += 1

這等於強迫第 i 個活動在第 i 天參加,完全沒有選擇的空間。像 [[1,5],[1,5],[1,5]] 可以參加 3 個,這版可以算對;但如果活動之間有空檔,time 不會跳到下一個活動開始的那天,結果就會錯。

正確解法
#

import heapq

class Solution:
    def maxEvents(self, events: List[List[int]]) -> int:
        events.sort()
        heap = []
        res = i = day = 0
        n = len(events)

        while i < n or heap:
            if not heap:
                day = events[i][0]                 # 沒有可參加的活動,直接跳到下一個開始日
            while i < n and events[i][0] <= day:
                heapq.heappush(heap, events[i][1])
                i += 1

            heapq.heappop(heap)                    # 參加最早結束的
            res += 1
            day += 1

            while heap and heap[0] < day:          # 丟掉已經結束的
                heapq.heappop(heap)
        return res

複雜度
#

時間 O(n log n):排序加上每個活動進出 heap 一次。空間 O(n)。

要特別避免的錯誤
#

  • 依開始日排序後直接一對一配對,沒有選擇「最早結束」的機制。
  • 沒有丟掉已經過期的活動:堆頂可能是早就結束的活動。
  • 一天一天往前走,沒有在 heap 空的時候跳到下一個開始日:天數最多 10^5,跳過可以省時間。

面試口說整理
#

我的貪心是每天參加已經開始的活動中最早結束的那個,因為晚結束的之後還有機會。依開始日排序,用 min-heap 存結束日:每天把開始的活動加進來,丟掉已經過期的,再取堆頂參加。heap 空的時候直接跳到下一個活動的開始日。時間 O(n log n)。

相關文章

LeetCode 3572: Maximize Y‑Sum by Picking a Triplet of Distinct X‑Values
·1 分鐘
LeetCode Medium Greedy Hash-Map Sorting
LeetCode 3572 解題筆記:每個 x 只留最大的 y,再取最大的三個
LeetCode 3075: Maximize Happiness of Selected Children
·1 分鐘
LeetCode Medium Array Greedy Sorting
LeetCode 3075 解題筆記:由大到小選 k 個,第 i 個選的會被扣 i,扣到 0 為止
LeetCode 324: Wiggle Sort II
·1 分鐘
LeetCode Medium Array Divide-and-Conquer Greedy Sorting
LeetCode 324 解題筆記:排序後分成小的一半和大的一半,各自反轉後交錯放:小的放偶數位置、大的放奇數位置
LeetCode 435: Non-overlapping Intervals
·1 分鐘
LeetCode Medium Array Dynamic-Programming Greedy Sorting
LeetCode 435 解題筆記:最少刪幾個 = 總數減掉最多能保留幾個;按右端點排序,貪心保留結束最早的
LeetCode 3607: Power Grid Maintenance
·2 分鐘
LeetCode Medium Heap Union-Find Graph Lazy-Deletion
LeetCode 3607 解題筆記:Union-Find 分群,每群一個 min-heap,離線的站用 lazy deletion
LeetCode 3608: Minimum Time for K Connected Components
·1 分鐘
LeetCode Medium Union-Find Graph Sorting Binary-Search
LeetCode 3608 解題筆記:倒過來從時間大的邊開始加回去,第一次讓連通塊數少於 k 的那條邊的時間就是答案