# LeetCode – Top K Frequent Elements (Java)

Given an array of integers, write a method to return the k most frequent elements.

Java Solution 1 - Heap

Time complexity is O(n*log(k)). Note that heap is often used to reduce time complexity from n*log(n) (see solution 3) to n*log(k).

```public List<Integer> topKFrequent(int[] nums, int k) { //count the frequency for each element HashMap<Integer, Integer> map = new HashMap<>(); for (int num : nums) { map.put(num, map.getOrDefault(num, 0) + 1); }   // create a min heap PriorityQueue<Map.Entry<Integer, Integer>> queue = new PriorityQueue<>(Comparator.comparing(e -> e.getValue()));   //maintain a heap of size k. for (Map.Entry<Integer, Integer> entry : map.entrySet()) { queue.offer(entry); if (queue.size() > k) { queue.poll(); } }   //get all elements from the heap List<Integer> result = new ArrayList<>(); while (queue.size() > 0) { result.add(queue.poll().getKey()); }   //reverse the order Collections.reverse(result);   return result; }```

Java Solution 2 - Bucket Sort

Time is O(n).

```public List<Integer> topKFrequent(int[] nums, int k) { //count the frequency for each element HashMap<Integer, Integer> map = new HashMap<>(); for(int num: nums){ map.put(num, map.getOrDefault(num, 0) + 1); }   //get the max frequency int max = 0; for(Map.Entry<Integer, Integer> entry: map.entrySet()){ max = Math.max(max, entry.getValue()); }   //initialize an array of ArrayList. index is frequency, value is list of numbers ArrayList<Integer>[] arr = (ArrayList<Integer>[]) new ArrayList[max+1]; for(int i=1; i<=max; i++){ arr[i]=new ArrayList<Integer>(); }   for(Map.Entry<Integer, Integer> entry: map.entrySet()){ int count = entry.getValue(); int number = entry.getKey(); arr[count].add(number); }   List<Integer> result = new ArrayList<Integer>();   //add most frequent numbers to result for(int j=max; j>=1; j--){ if(arr[j].size()>0){ for(int a: arr[j]){ result.add(a); //if size==k, stop if(result.size()==k){ return result; } } } }   return result; }```
Category >> Algorithms
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
```<pre><code>
String foo = "bar";
</code></pre>
```
• sherry

Solution 1, you can directly store Map.Entry in PriorityQueue and you don’t need to create Pair.
PriorityQueue<Map.Entry> minHeap = new PriorityQueue(k, new comparator<Map.Entry() {//…});

• Bukary Kandeh

Shortest Java solution with good efficiency. See my solution, I have added comments. Time is O(n).

``` public static int topKFrequentArray(int[] array, int k){```

``` /* First get element and number of occurrence using HashMap */ Map hm = new HashMap(); for(int i : array){ if(hm.containsKey(i)){ hm.put(i, hm.get(i) + 1); } else {hm.put(i, 1);} } /*Since Map does not allow dups keys, let's swap the key & value and insert into multimap. This sorts it as well */ Multimap mp = ArrayListMultimap.create(); for(Map.Entry m : hm.entrySet()){ mp.put(m.getValue(),m.getKey()); } ```

``` /* Finally we extract all values (ordered by smallest) and load into a list */ List ls = new ArrayList(); Set ks = mp.keySet(); Iterator it = ks.iterator(); while (it.hasNext() ) { ls.addAll(new ArrayList(mp.get((Integer) it.next()))); } /* Since the biggest is last of the list, we substract k from the List Size */ return ls.get(ls.size()-k); } ```

• Bukary Kandeh

``` My slick java solution, easy to understand and very efficient. Time is O(n).```

``` public static int topKFrequent(int[] array, int k){ Map hm = new HashMap(); Multimap mp = ArrayListMultimap.create(); List ls = new ArrayList(); for(int i : array){ if(hm.containsKey(i)){hm.put(i, hm.get(i) + 1); } else {hm.put(i, 1);} } for(Map.Entry m : hm.entrySet()){mp.put(m.getValue(),m.getKey());} Set ks = mp.keySet(); Iterator it = ks.iterator(); while (it.hasNext() ) { Collection val = mp.get((Integer) it.next()); for(int i : val){ls.add(i);} } ```

``` System.out.println("Print " +k+" Character"); for(int i=ls.size()-1, cnt=1; i>=0; cnt++, i--){if(cnt == k){return ls.get(i);}} return 0; } ```

• ryanlr

Fixed. Thanks!

• Ed

There’s a bug in solution 2-
//add most frequent numbers to result
for(int j=max; j>=1; j–){
if(arr[j].size()>0){
for(int a: arr[j]){
}
}

if(result.size()==k)
break;
}

The check for result.size()==k should be inside the loop after result.add(a). This is because result.size() == k can occur when your looping each int a.

• Longqi Zhang

Java Solution 2 – Bucket Sort has bug.
Try this array to test:
``` int a[] = {1, 2, 4, 2, 2, 5, 1, 4, 2, 1, 4, 2}; int k=2; ```

The code below:
``` if (result.size() == k) { break; } ```
should be changed to:
``` if (result.size() >= k) { break; } ```

• Ankit Shah

Treemap code can be as concise as this:

``` Map sortedMap = new TreeMap(new Comparator() { public int compare(Integer o1, Integer o2) { int diff = map.get(o2) - map.get(o1); return diff == 0 ? 1 : diff; } }); sortedMap.putAll(counter); ```

• Sudhakar R

Second solution i think the code to populate result should look like this.

for(int j=max; j>=k-1; j–){
if(count[j].size()>0){
for(int a: count[j]){