力扣347(前k個高頻元素)
阿新 • • 發佈:2021-11-04
347、前k個高頻元素
基本思想:
對頻率進行排序,
使用優先順序佇列
具體實現:
什麼是優先順序佇列呢?
1、對外介面從隊頭取元素,從隊尾新增元素,再無其他取元素的方式
2、優先順序佇列內部元素是自動依照元素的權值排列。
如何有序排列?
使用堆
堆是一顆完全二叉樹,樹中每個結點的值都不小於(或不大於)其左右孩子的值。
如果父親結點是大於等於左右孩子就是大頂堆,小於等於左右孩子就是小頂堆。
此題用小頂堆,因為要統計最大前k個元素,只有小頂堆每次將最小的元素彈出,最後小頂堆裡積累的才是前k個最大元素。
程式碼:
class Solution { public int[] topKFrequent(int[] nums, int k) { int[] result = new int[k]; HashMap<Integer, Integer> map = new HashMap<>(); for (int num : nums){ map.put(num, map.getOrDefault(num, 0) + 1); // map.put,將指定key-value新增到(或修改)當前map物件中 //map.getOrDefault,當map集合中有這個num時,就使用這個num值;如果沒有就使用0。} Set<Map.Entry<Integer, Integer>> entries = map.entrySet(); //Set entrySet():返回所有key-value對構成的Set集合 PriorityQueue<Map.Entry<Integer, Integer>> queue = new PriorityQueue<>((o1, o2) -> o1.getValue() - o2.getValue()); for (Map.Entry<Integer, Integer> entry : entries) { queue.offer(entry);if (queue.size() > k) { queue.poll(); } } // 找出前K個高頻元素,因為小頂堆先彈出的是最小的,所以倒敘來輸出到陣列 // for (int i = k - 1; i >= 0; i--) { // result[i] = queue.poll().getKey(); // } // return result; for (int i = 0; i < k; i++) { result[i] = queue.poll().getKey(); } return result; } }