Top k 個頻繁元素 | Medium | LeetCode#347. Top K Frequent Elements
題目敘述
- 題目難度:
Medium
- 題目描述: 給定一個整數陣列
nums
以及整數k
並回傳nums
中k
個出現最頻繁的元素,你可以以任意順序回傳答案
本題限制
1 <= nums.length <= 105
1 <= k <= nums.length
解法
一開始的想法
看到這種前 k
個,k
個最頻繁,十有八九最佳解會是用 priority queue 去解
我的解法
1 | class Solution { |
思路解析
這題的 nums
範圍限制在 -10000
到 10000
,所以整體數字數量並不大,最多 20001 種可能。
基於這個前提,我的解法流程如下:
統計出現頻率
建立一個大小為20001
的陣列numCount
,利用 index 代表數字本身。因為數字可能為負數,所以我把數字 n mapping成 n+10000,保證 index 為正整數丟入max heap
每個數字與它的出現次數組合成一個pair<int,int>
,放進 priority queue。 C++ STL 的priority_queue
預設是 max heap,但它針對 pair 型別的預設排序並不是 依照第二個元素。 所以我自訂了一個比較器comparator
,讓它專門比較pair.second
,也就是「出現次數」。
decltype(comparator)
的作用是自動推導 lambda 的型別,這樣才能把它當成參數傳給 priority_queue
- 取出前 k 個元素
從max heap中 pop 出來的元素,會依照出現頻率由大到小排列。 我們只要取出前 k 個就能得到答案。
這邊的lambda寫法可以參考這篇:https://notes.boshkuo.com/docs/C++/STL/priority_queue
執行結果
複雜度
時間複雜度: $O(mlogm)$,m 最壞狀況會是 20001,取出前 k 個會是 $(klogm)$,建立頻率表會是 $O(n)$ 所以嚴格來說應該會是 $O(n + mlogm)$
空間複雜度: $O(m)$, m 為priority queue 最多塞m個元素
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Kevin Liu's 部落格 || Technical || Travel!
評論