Top K Frequent Elements
Problem (restated)
Return the k most frequent elements in any order. The answer is unique.
Intuition
Count frequencies, then bucket by frequency so the densest buckets are at the end.
Approaches
Frequency buckets
UnverifiedIdea. Map value→count. buckets[c] holds values with count c. Scan buckets from high to low.
Walkthrough. [1,1,1,2,2,3], k=2 → 1 has freq 3, 2 has 2 → [1,2].
Trade-offs. Heap is O(n log k). Frequency is at most n, so scanning buckets is O(n) worst-case.
export function topKFrequent(nums: number[], k: number): number[] {
const freq = new Map<number, number>();
for (const x of nums) freq.set(x, (freq.get(x) ?? 0) + 1);
const buckets: number[][] = Array.from({ length: nums.length + 1 }, () => []);
for (const [val, c] of freq) buckets[c]!.push(val);
const out: number[] = [];
for (let c = buckets.length - 1; c >= 0 && out.length < k; c--) {
for (const v of buckets[c]!) {
out.push(v);
if (out.length === k) return out;
}
}
return out;
}
export function topKFrequent(nums: number[], k: number): number[] {
const freq = new Map<number, number>();
for (const x of nums) freq.set(x, (freq.get(x) ?? 0) + 1);
const buckets: number[][] = Array.from({ length: nums.length + 1 }, () => []);
for (const [val, c] of freq) buckets[c]!.push(val);
const out: number[] = [];
for (let c = buckets.length - 1; c >= 0 && out.length < k; c--) {
for (const v of buckets[c]!) {
out.push(v);
if (out.length === k) return out;
}
}
return out;
}
Template connection
Count with a hash map, then bucket by frequency (heap / quick-select also work).
Reflection
- A frequency map, then buckets. When the highest frequency is
n, why is that O(n) rather than a heap of sizek? - The set of answers is fixed, but the order is free. Do the tests require a particular order?
- When
k = n, is there anything left for a heap to win?