LeetCode347. 前K個高頻元素
阿新 • • 發佈:2019-02-09
今天繼續哈,寫的還是比較簡單的一個題,雜湊表和堆排序,要多多熟悉java的資料結構。
題目
給定一個非空的整數陣列,返回其中出現頻率前 k 高的元素。
例如,
給定陣列 [1,1,1,2,2,3]
, 和 k = 2,返回 [1,2]
。
注意:
- 你可以假設給定的 k 總是合理的,1 ≤ k ≤ 陣列中不相同的元素的個數。
- 你的演算法的時間複雜度必須優於 O(n log n) , n 是陣列的大小。
分析
看到給出一個數組,輸出頻率最高的第一反應就是雜湊表嘛, 因為輸出頻率前k高的元素,所以要進行一次排序,注意裡要求,時間複雜度必須優於O(n log n),堆排序是時間複雜度為O(n log n),這樣就用了優先佇列PriorityQueue。
首先遍歷陣列,將陣列中的數字和出現的對應頻率存入map中,這裡可以把map中的鍵值對分散為一個一個的Map.Entry<K,V>,對value排序存放入堆中,最後將前k大的出隊。
java的優先佇列預設為小頂堆,在建立堆的時候要寫一下比較器,通過entry的value值進行降序排序。
程式碼
class Solution { public List<Integer> topKFrequent(int[] nums, int k) { List<Integer> list = new ArrayList<>(); PriorityQueue<Map.Entry<Integer,Integer>> pq = new PriorityQueue<>(new Comparator<Map.Entry<Integer, Integer>>() { @Override public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) { return o2.getValue()-o1.getValue(); } }); Map<Integer,Integer> map = new HashMap<>(); for (int i = 0; i < nums.length; i++) if (map.containsKey(nums[i])) map.put(nums[i],map.get(nums[i])+1); else map.put(nums[i],1); Set<Map.Entry<Integer,Integer>> set = map.entrySet(); for (Map.Entry<Integer,Integer> entry : set) pq.add(entry); for (int i = 0; i < k; i++) list.add(pq.poll().getKey()); return list; } }
因為一開始沒有注意到Map.Entry這個的存在,想要在優先佇列中存放鍵值對可是不知道使用什麼資料結構,之後看了結題報告才明白,所以要好好熟悉資料結構。
Map.Entry
對映項(鍵-值對)。Map.entrySet 方法返回對映的 collection 檢視,其中的元素屬於此類。獲得對映項引用的唯一 方法是通過此 collection 檢視的迭代器來實現。這些 Map.Entry 物件僅 在迭代期間有效;更確切地講,如果在迭代器返回項之後修改了底層對映,則某些對映項的行為是不確定的,除了通過 setValue 在對映項上執行操作之外。