Link: https://leetcode.com/problems/top-k-frequent-elements/
Constraints:
1 <= nums.length <= 105
k is in the range [1, the number of unique elements in the array].
It is guaranteed that the answer is unique.
Idea
We could use priority heap to keep track of the K least frequent elements, by implementing our own comparator. Everytime the size of the heap is larger than K, we pop elemnt from the heap. This way we make sure the remaining K elements are the most frequent.
Code
class Solution {
public int[] topKFrequent(int[] nums, int k) {
Map<Integer, Integer> numberFrequencyMap = new HashMap<>();
for (int n : nums) {
if (!numberFrequencyMap.containsKey(n)) {
numberFrequencyMap.put(n, 1);
} else {
numberFrequencyMap.put(n, numberFrequencyMap.get(n) + 1);
}
}
PriorityQueue<Element> pq = new PriorityQueue<>();
for (int n : numberFrequencyMap.keySet()) {
Element element = new Element(n, numberFrequencyMap.get(n));
pq.offer(element);
while (pq.size() > k) {
pq.poll();
}
}
int[] results = new int[k];
for (int i = 0; i < k && !pq.isEmpty(); i++) {
Element element = pq.poll();
results[i] = element.num;
}
return results;
}
private class Element implements Comparable<Element> {
int num;
int count;
Element(int num, int count) {
this.num = num;
this.count = count;
}
@Override
public int compareTo(Element other) {
return this.count - other.count;
}
}
}
- Time: O(nlogk) as the time to do offer()/poll() against a min heap with size k is (logk).
- Space: O(n). The map needs to have a entry for all unique words in the array.
This question can also be solved using Bucket sort with O(n) time, as shown in this link.
Similar problem: