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

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

703Kth Largest Element in a StreamHeap / Priority QueueEasyHeap / Priority Queue

設計一個類別,能找到資料流中第 k 大的元素。注意是排序後第 k 大,不是第 k 個不同的元素。實作 KthLargest 類別,包含建構子和 add 方法。

Example:

Input: [“KthLargest”, “add”, “add”, “add”, “add”, “add”] [[3, [4, 5, 8, 2]], [3], [5], [10], [9], [4]] Output: [null, 4, 5, 5, 8, 8]

Intuition

TIP

核心思路:維護一個大小為 k 的 Min Heap,堆頂就是第 k 大的元素。

Approaches

1. Sorting — O(n log n) / O(n)
  • Idea: 每次 add 時,將所有元素排序,取第 k 大的元素
  • Time: O(n log n) 每次 add
  • Space: O(n)
class KthLargest(k: Int, nums: IntArray) {
    private val k = k
    private val list = nums.toMutableList()

    fun add(`val`: Int): Int {
        list.add(`val`)
        list.sort()
        return list[list.size - k]
    }
}
⭐ 2. Min Heap — O(log k) / O(k)
  • Idea: 用大小為 k 的 Min Heap,堆頂永遠是第 k 大的元素。新增元素時若 heap 大小超過 k,彈出堆頂
  • Time: O(log k) 每次 add,建構子 O(n log k)
  • Space: O(k)
class KthLargest(k: Int, nums: IntArray) {
    private val k = k
    private val minHeap = PriorityQueue<Int>()

    init {
        for (num in nums) {
            add(num)
        }
    }

    fun add(`val`: Int): Int {
        minHeap.offer(`val`)
        if (minHeap.size > k) {
            minHeap.poll()
        }
        return minHeap.peek()
    }
}

🔑 Takeaways

Ladders 看全部 →

⛰️

Top-K / 第 K 大

quickselect、堆、桶排序各擅勝場。

  1. 1#215Kth Largest Element in an ArrayMedium第 K 大:quickselect 或最小堆
  2. 2#347Top K Frequent ElementsMedium前 K 高頻:桶排序 / 堆
  3. 3#973K Closest Points to OriginMedium最近 K 個點:以距離為鍵的堆
  4. 4