Given a non-empty array of integers, return the k most frequent elements.
For example,
Given [1,1,1,2,2,3]
and k = 2, return [1,2]
.
Note:
- You may assume k is always valid, 1 ≤ k ≤ number of unique elements.
- Your algorithm's time complexity must be better than O(n log n), where n is the array's size
Analysis:
We can use bucket sort style solution: Since the largest frequency is N, we can use a size N array to store the element with each possible frequency.
Solution:
1 public class Solution { 2 public List<Integer> topKFrequent(int[] nums, int k) { 3 List<Integer> res = new ArrayList<Integer>(); 4 if (nums.length==0 || k==0) return res; 5 6 List<Integer>[] freqList = new List[nums.length+1]; 7 Map<Integer,Integer> freqMap = new HashMap<Integer,Integer>(); 8 9 // Get frequencey map 10 for (int num: nums){ 11 freqMap.put(num,freqMap.getOrDefault(num,0)+1); 12 } 13 14 // According to each num's frequency, put it into frequency list 15 for (int num: freqMap.keySet()){ 16 int freq = freqMap.get(num); 17 if (freqList[freq]==null){ 18 freqList[freq] = new ArrayList<Integer>(); 19 } 20 freqList[freq].add(num); 21 } 22 23 int left = k; 24 for (int i=freqList.length-1;i>=0 && left>0;i--){ 25 if (freqList[i]!=null){ 26 if (left>=freqList[i].size()){ 27 res.addAll(freqList[i]); 28 left -= freqList[i].size(); 29 } else { 30 for (int j=0;j<left;j++) res.add(freqList[i].get(j)); 31 break; 32 } 33 } 34 } 35 36 return res; 37 } 38 }