Given an integer array nums
and an integer k
, return the k
most frequent elements. You may return the answer in any order.
題目摘要
nums
和一個整數 k
,要求返回出現頻率最高的 k
個元素。nums
:一個包含 n
個整數的陣列、k
:要求返回的頻率最高的元素個數。k
個整數的陣列。Example 1:
Input: nums = [1,1,1,2,2,3], k = 2
Output: [1,2]
Example 2:
Input: nums = [1], k = 1
Output: [1]
解題思路
HashMap
(frequencyMap
)來儲存每個元素的頻率。k
高的元素:
PriorityQueue
(minHeap
)實現minHeap。minHeap的大小維持為 k
,這樣可以確保Heap中始終包含頻率最高的 k
個元素。frequencyMap
中的每一個 Map.Entry
(頻率-數字對),將它們加入最小堆。k
時,移除堆頂元素(頻率最小的元素)。result
列表中。程式碼
class Solution {
public int[] topKFrequent(int[] nums, int k) {
Map<Integer, Integer> frequencyMap = new HashMap<>(); //設立一個HashMap來計算每個元素的頻率
//遍歷整個陣列
for (int num : nums) {
frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1); //更新每個元素的頻率
}
//使用最小堆來維護頻率最高的k個元素,頻率較低的元素會被移除
PriorityQueue<Integer> minHeap = new PriorityQueue<>(
(n1, n2) -> frequencyMap.get(n1) - frequencyMap.get(n2)
);
//
for (int num : frequencyMap.keySet()) {
minHeap.add(num); //將每個元素加入最小堆
//如果堆的大小超過k,移除最小的元素
if (minHeap.size() > k) {
minHeap.poll();
}
}
int[] result = new int[k]; //設立一個結果陣列來儲存頻率最高的k個元素
//堆中存儲的是頻率最高的k個元素,將最小堆中的元素放入結果陣列中
for (int i = 0; i < k; i++) {
result[i] = minHeap.poll();
}
return result; //回傳結果陣列
}
}
結論: 在寫這題時,完全沒有思緒如何去寫出一個minHeap,甚至還要能使其一直維持著minHeap該有的規則。就這樣腦袋空空的去參考了LeetCode上許多人分享的解題影片、文章,甚至直接研讀程式碼,才第一次跳出了課本上教的排序知識,第一次接觸到這樣的排序是該如何透過程式碼去實現。覺得是非常有趣的!過去學習的各種排序演算法,只是在書上學習了和Day13那天文章的理論知識,從沒想過要如何用程式碼實現,是很新奇又興奮的一次機會!