Skip to content

Commit 9640728

Browse files
Top K frequent elements
1 parent e937012 commit 9640728

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package medium;
2+
3+
import java.util.ArrayList;
4+
import java.util.Comparator;
5+
import java.util.HashMap;
6+
import java.util.List;
7+
import java.util.Map;
8+
import java.util.Map.Entry;
9+
import java.util.PriorityQueue;
10+
import java.util.Queue;
11+
12+
public class TopKFrequentElements {
13+
// Approach 1: use buckets to hold numbers of the same frequency
14+
/**Attn: we must use a simple array to solve this problem, instead of using List<List<Integer>>,
15+
* we have to use List<Integer>[], otherwise, cases like this one: [-1,-1]
16+
* 1 will fail due to the fact that ArrayList.get(i),
17+
* this i must be a non-negative number, however, in simple arrays, the index could be negative.
18+
* Although in this question, frequency will be at least 1, but still in problems like this where bucket sort
19+
* works the best, you should use List<Integer>[], this will simplify the code.*/
20+
public List<Integer> topKFrequent_using_bucket(int[] nums, int k) {
21+
Map<Integer, Integer> map = new HashMap();
22+
for(int i : nums){
23+
map.put(i, map.getOrDefault(i, 0)+1);
24+
}
25+
26+
ArrayList[] bucket = new ArrayList[nums.length+1];
27+
for(Map.Entry<Integer, Integer> e : map.entrySet()){
28+
int frequency = e.getValue();
29+
if(bucket[frequency] == null){
30+
bucket[frequency] = new ArrayList<Integer>();
31+
}
32+
bucket[frequency].add(e.getKey());
33+
}
34+
List<Integer> result = new ArrayList<Integer>();
35+
for(int i = bucket.length-1; i >= 0 && result.size() < k; i--){
36+
if(bucket[i] != null) result.addAll(bucket[i]);
37+
}
38+
39+
return result;
40+
}
41+
42+
// Approach 2: use hashtable and heap
43+
/**
44+
* Bonus tips on how to write a priority queue:
45+
*
46+
* Tip1:
47+
* it should be like this:
48+
* PriorityQueue's angle brackets should be left blank, the type should be in
49+
* Comparator's angle brackets and the compare method should be in Comparator's
50+
* brackets. new PriorityQueue<>(new Comparator<int[]>(){ public int
51+
* compare(int[] o1, int[] o2){ } })
52+
*
53+
* Tip2:
54+
* if you want things in DEscending order, then if(01 > o2), it should return -1
55+
* if Ascending order, then if(01 > o2), it should return 1
56+
*/
57+
public List<Integer> topKFrequent_using_heap(int[] nums, int k) {
58+
Map<Integer, Integer> map = new HashMap();
59+
Queue<Map.Entry<Integer, Integer>> heap = new PriorityQueue<>(new Comparator<Map.Entry<Integer, Integer>>() {
60+
@Override
61+
public int compare(Entry<Integer, Integer> o1, Entry<Integer, Integer> o2) {
62+
if (o1.getValue() > o2.getValue())
63+
return -1;
64+
else if (o1.getValue() < o2.getValue())
65+
return 1;
66+
return 0;
67+
}
68+
});
69+
70+
// construct the frequency map first, and then iterate through the map
71+
// and put them into the heap, this is O(n)
72+
for (int x : nums) {
73+
if (map.containsKey(x))
74+
map.put(x, map.get(x) + 1);
75+
else
76+
map.put(x, 1);
77+
}
78+
79+
// build heap, this is O(n) as well
80+
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
81+
heap.offer(entry);
82+
}
83+
84+
List<Integer> res = new ArrayList<Integer>();
85+
while (k-- > 0) {
86+
res.add(heap.poll().getKey());
87+
}
88+
return res;
89+
}
90+
91+
public static void main(String[] args) {
92+
int[] nums = new int[] { 3, 0, 1, 0 };
93+
TopKFrequentElements test = new TopKFrequentElements();
94+
test.topKFrequent_using_heap(nums, 1);
95+
// test.topKFrequent_using_bucket(nums, 1);
96+
}
97+
98+
}

0 commit comments

Comments
 (0)