Top K Frequent Elements
Given an integer array nums and an integer k, return the top k frequent elements in the array.
Constraints:
- 1 <= nums.length <= 10^5
- 1 <= k <= 10^5
- It is guaranteed that the answer is unique.
Examples:
Input: [1,1,1,2,2,3] and k = 2
Output: [1,2]
Explanation: The elements 1 and 2 are the top 2 frequent elements in the array.
Solutions
Hash Table and Heap
We use a hash table to count the frequency of each element in the array. Then we use a max heap to find the top k frequent elements.
function topKFrequent(nums, k) {
const count = {};
for (let num of nums) {
count[num] = (count[num] || 0) + 1;
}
const maxHeap = new MaxHeap(
Object.keys(count),
(a, b) => count[b] - count[a]
);
const result = [];
for (let i = 0; i < k; i++) {
result.push(maxHeap.extractMax());
}
return result;
}
class MaxHeap {
constructor(data, comparator) {
this.data = data;
this.comparator = comparator;
this.heapify();
}
heapify() {
for (let i = Math.floor(this.data.length / 2) - 1; i >= 0; i--) {
this.siftDown(i);
}
}
siftDown(index) {
let smallest = index;
let left = 2 * index + 1;
let right = 2 * index + 2;
if (
left < this.data.length &&
this.comparator(this.data[smallest], this.data[left]) > 0
) {
smallest = left;
}
if (
right < this.data.length &&
this.comparator(this.data[smallest], this.data[right]) > 0
) {
smallest = right;
}
if (smallest !== index) {
[this.data[index], this.data[smallest]] = [
this.data[smallest],
this.data[index],
];
this.siftDown(smallest);
}
}
extractMax() {
if (this.data.length === 0) return null;
if (this.data.length === 1) return this.data.pop();
const max = this.data[0];
this.data[0] = this.data.pop();
this.siftDown(0);
return max;
}
}
Follow-up:
What if the input array is very large and does not fit into memory?