Tuesday, May 31, 2016

Top K Frequent Elements

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.
solution is similar to bucket sort.  with help or hash table, this can be O(n).
1. calculate statistics of frequency by using hash table/map
2. putting map entries to priority queue by defining proper comparator that makes it sorting by frequency high to low


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class Solution {
    public List<Integer> topKFrequent(int[] nums, int k) {
  HashMap<Integer,Integer> frequencyMap = new HashMap<Integer,Integer>();
  //counte frequence with dict/hashmap/hashtable
  for(int i=0;i<nums.length;i++){
   if(frequencyMap.get(nums[i])==null){
    frequencyMap.put(nums[i],1); 
   }
   else{
    frequencyMap.put(nums[i],frequencyMap.get(nums[i])+1);
   }
  }
  //sort according to frequency by putting them in priority queue backed by reversed number order
  PriorityQueue<Map.Entry<Integer, Integer>> pq= 
    new PriorityQueue<Map.Entry<Integer, Integer>>(
    new Comparator<Map.Entry<Integer, Integer>>(){
     public int compare(Map.Entry<Integer, Integer> e1,Map.Entry<Integer, Integer> e2){
      return e2.getValue()-e1.getValue();
    }
    });
  pq.addAll(frequencyMap.entrySet());
  List<Integer> aList = new ArrayList<Integer>();
  //retrieve top k numbers
  while(k>0&&!pq.isEmpty()){
   k--;
   aList.add(pq.poll().getKey());
  }
  return aList;
    }
}

No comments: