Medium草稿★★★★★O(log n) 時間 · O(m) 空間
HeapPriority QueueDesign
Patterns🏗️ 資料結構設計⛰️ 堆・Top-K
尚未複習過

解法已隱藏 — 先讀題目敘述、自己想想看,再點上方按鈕揭曉。

1845Seat Reservation ManagerHeap / Priority QueueMediumHeap / Priority Queue

設計一個座位預約管理系統。系統管理從 1 到 n 編號的座位。實作 SeatManager 類別:SeatManager(int n) 初始化,reserve() 預約並回傳最小編號的未預約座位,unreserve(int seatNumber) 取消預約。

Example:

Input: [“SeatManager”, “reserve”, “reserve”, “unreserve”, “reserve”, “reserve”, “reserve”, “reserve”, “unreserve”] [[5], [], [], [2], [], [], [], [], [5]] Output: [null, 1, 2, null, 2, 3, 4, 5, null]

Intuition

TIP

核心思路:用 Min Heap 維護所有可用座位,reserve 取堆頂,unreserve 加回 heap。

Approaches

1. Min Heap (preload all) — Init O(n), reserve O(log n) / O(n)
  • Idea: 初始化時將 1 到 n 全部加入 Min Heap
  • Time: 初始化 O(n),reserve/unreserve O(log n)
  • Space: O(n)
class SeatManager(n: Int) {
    private val minHeap = PriorityQueue<Int>()

    init {
        for (i in 1..n) minHeap.offer(i)
    }

    fun reserve(): Int = minHeap.poll()

    fun unreserve(seatNumber: Int) {
        minHeap.offer(seatNumber)
    }
}
⭐ 2. Min Heap + Lazy Initialization — reserve O(log n) / O(m)
  • Idea: 用計數器 nextSeat 延遲分配座位,heap 只存被 unreserve 回收的座位,避免初始化大量元素
  • Time: reserve/unreserve O(log n)
  • Space: O(m) - m 為 unreserve 的次數
class SeatManager(n: Int) {
    private val minHeap = PriorityQueue<Int>()
    private var nextSeat = 1

    fun reserve(): Int {
        return if (minHeap.isNotEmpty()) {
            minHeap.poll()
        } else {
            nextSeat++
            nextSeat - 1
        }
    }

    fun unreserve(seatNumber: Int) {
        minHeap.offer(seatNumber)
    }
}

🔑 Takeaways