My First PriorifyQueue Solution
This soltion use a Map to record the frequency of every number, and then use PriorityQueue to sort by frequency. The time complexity is O(nlogn), two pass.
class NumCount{ public NumCount(int num, int count){ this.num = num; this.count = count; } public int num=0; public int count = 0; } public int[] topKFrequent(int[] nums, int k) { Map<Integer, Integer> map = new HashMap<>(); for(int i=0;i<nums.length;i++){ map.putIfAbsent(nums[i], 0); map.put(nums[i], map.get(nums[i])+1); } PriorityQueue<NumCount> queue = new PriorityQueue<>((a, b)->b.count-a.count); Set<Integer> set = map.keySet(); for(int num: set){ NumCount n = new NumCount(num, map.get(num)); queue.add(n); } int[] res = new int[k]; for(int i=0;i<k;i++){ res[i]=queue.poll().num; } return res; }
My Second Bucket Sort Solution
The time conplexity is O(n), because the sorting has been done when put the numbers in buckets.
public int[] topKFrequent(int[] nums, int k) { List<Integer>[] bucket = new List[nums.length+1]; Map<Integer, Integer> map = new HashMap<>(); for(int i=0;i<nums.length;i++){ map.putIfAbsent(nums[i], 0); map.put(nums[i], map.get(nums[i])+1); } Set<Integer> set = map.keySet(); for(int num: set){ int freq = map.get(num); if(bucket[freq]==null){ bucket[freq]=new ArrayList<>(); } bucket[freq].add(num); } int[] res = new int[k]; int j=0; for(int i=bucket.length-1;i>=0;i--){ if(bucket[i]==null) continue; List<Integer> list = bucket[i]; for(int n: list){ if(j>=k) return res; res[j++]=n; } } return res; }
Or a Queue can be used:
class Solution { public int[] topKFrequent(int[] nums, int k) { Map<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < nums.length; i++) { map.put(nums[i], map.getOrDefault(nums[i], 0) + 1); } Queue<Integer>[] buckets = new LinkedList[nums.length + 1]; Set<Integer> set = map.keySet(); for (int n : set) { int freq = map.get(n); if (buckets[freq] == null) { buckets[freq] = new LinkedList<>(); } buckets[freq].add(n); } int[] res = new int[k]; int j = 0; for (int i = buckets.length - 1; i >= 0; i--) { if (buckets[i] == null) continue; Queue<Integer> queue = buckets[i]; while (!queue.isEmpty()) { if (j >= k) return res; res[j++] = queue.poll(); } } return res; } }