Min Heap + HashMap
Time Complexity = O(n + nlogk) = O(nlogk). O(n) to build hashmap. O(nlogk) for constructing heap.
Space Complexity = O(n + logk) = O(n). O(n) to store hashmap. O(logk) for constructing heap.
2022 New code:
class Solution {
public int[] topKFrequent(int[] nums, int k) {
if (k == nums.length) {
return nums;
}
// 1. build hash map : character and how often it appears
// O(N) time
Map<Integer, Integer> count = new HashMap();
for (int n: nums) {
count.put(n, count.getOrDefault(n, 0) + 1);
}
// init heap 'the less frequent element first'
Queue<Integer> heap = new PriorityQueue<>(
(n1, n2) -> count.get(n1) - count.get(n2));
// 2. keep k top frequent elements in the heap
// O(N log k) < O(N log N) time
for (int n: count.keySet()) {
heap.add(n);
if (heap.size() > k) {
heap.poll();
}
}
// 3. build an output array
// O(k log k) time
int[] top = new int[k];
for(int i = k - 1; i >= 0; i--) {
top[i] = heap.poll();
}
return top;
}
}
Old code:
class Solution {
public List<Integer> topKFrequent(int[] nums, int k) {
List<Integer> res = new ArrayList<>();
if (nums == null || nums.length == 0) {
return res;
}
Map<Integer, Integer> map = new HashMap<>();
for (int num : nums) {
if (!map.containsKey(num)) {
map.put(num, 1);
} else {
map.put(num, map.get(num) + 1);
}
}
PriorityQueue<Map.Entry<Integer, Integer>> minHeap = new PriorityQueue<>(k, new Comparator<Map.Entry<Integer, Integer>>() {
@Override
public int compare(Map.Entry<Integer, Integer> entry1, Map.Entry<Integer, Integer> entry2) {
return entry1.getValue() - entry2.getValue();
}
});
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
minHeap.offer(entry);
if (minHeap.size() > k) {
minHeap.poll();
}
}
while (!minHeap.isEmpty()) {
res.add(minHeap.poll().getKey());
}
Collections.reverse(res);
return res;
}
}
TODO