# 0347. Top K Frequent Elements ###### tags: `Leetcode` `Medium` `Top K Elements` `FaceBook` Link: https://leetcode.com/problems/top-k-frequent-elements/ ## 思路 ### 思路一 Priority Queue 很简单的思路,但是要**注意语法 priority queue的声明,以及如何定义排序方法** 先遍历一遍,然后用Map存每个数出现的次数 再用priority queue对出现的次数排序 如果queue的size大于k就用poll()把多余的扔掉 ### 思路二 Quick sort ![](https://i.imgur.com/mHUgWCc.png) ### 思路三 Bucket Sort 但桶排序只适用于最大值比较小的情况,如果是找top k 大的值,用桶排序时间和空间复杂度就会比较高,因为array会非常大 先用map统计count,然后用一个array of list存每个频率对应的数字们 **注意array of list的声明 ```List<Integer>[] bucket = new List [nums.length+1];```** ## Code in Java ### 思路一 ```java= public int[] topKFrequent(int[] nums, int k) { Map<Integer,Integer> count = new HashMap(); for(int n:nums){ count.put(n,count.getOrDefault(n,0)+1); } PriorityQueue<Integer> queue = new PriorityQueue<>( (n1,n2) -> count.get(n1)-count.get(n2) ); for(int n:count.keySet()){ queue.add(n); if(queue.size()>k){ queue.poll(); } } int[] top = new int[k]; for(int i = k-1;i >= 0;i--){ top[i] = queue.poll(); } return top; } ``` ### 思路二 ```java= class Solution { public int[] topKFrequent(int[] nums, int k) { Map<Integer,Integer> count = new HashMap(); for(int n:nums){ count.put(n,count.getOrDefault(n,0)+1); } List<int[]> values = new ArrayList<int[]>(); for (Map.Entry<Integer,Integer> entry:count.entrySet()){ int key = entry.getKey(); int val = entry.getValue(); values.add(new int[]{key,val}); } int[] ret = new int[k]; qsort(values,0,values.size()-1, k, ret, 0); return ret; } public static void qsort(List<int[]> values, int start, int end, int k, int[] ret, int retIndex){ int picked = (int)(Math.random()*(end-start+1))+start; Collections.swap(values,picked,start); int pivot = values.get(start)[1]; int index = start; for(int i = start+1;i <= end;i++){ if(values.get(i)[1]>pivot){ Collections.swap(values,index+1,i); index++; } } Collections.swap(values,start,index); if(index-start+1<=k){ for(int i = start;i <= index;i++){ ret[retIndex++] = values.get(i)[0]; } if(k>index-start+1){ qsort(values, index+1, end, k-(index-start+1), ret, retIndex); } } else{ qsort(values, start, index-1, k, ret, retIndex); } } } ``` ### 思路三 ```java= class Solution { public int[] topKFrequent(int[] nums, int k) { Map<Integer, Integer> count = new HashMap<>(); for(int i = 0;i < nums.length;i++){ count.put(nums[i], count.getOrDefault(nums[i],0)+1); } List<Integer>[] bucket = new List [nums.length+1]; for(int key:count.keySet()){ int frequency = count.get(key); if(bucket[frequency]==null) bucket[frequency] = new ArrayList<>(); bucket[frequency].add(key); } int[] ans = new int[k]; int idx = 0; for(int i = bucket.length-1; i >= 0 && idx < k;i--){ if(bucket[i]!=null){ for(int j = 0; j < bucket[i].size() && idx < k;j++){ ans[idx++] = bucket[i].get(j); } } } return ans; } } ``` ## Result ### 思路一 Runtime: 11 ms, faster than **55.15%** of Java online submissions for Top K Frequent Elements. Memory Usage: 41.5 MB, less than **82.08%** of Java online submissions for Top K Frequent Elements. ### 思路二 Runtime: 9 ms, faster than **87.07%** of Java online submissions for Top K Frequent Elements. Memory Usage: 41.6 MB, less than **73.34%** of Java online submissions for Top K Frequent Elements.