Top K Frequent Elements
Problem statement
From an integer list, return any k values that show up most often.
Example:
Input:
numbers = [1, 2, 3, 4, 5, 6, 1, 2, 1, 2], k = 2
Expected output:
[1, 2]
Why: 1 and 2 appear more than anything else.
Practice on LeetCode: Top K Frequent Elements
Approach 1: Hash map + sort
Count frequencies in a hash map, collect the unique keys, and sort them by frequency descending. Return the first k keys.
Time: O(n + m log m) where m is the number of unique values (m ≤ n).
Space: O(m).
package main
import "sort"
func topKFrequent(nums []int, k int) []int {
hashMap := make(map[int]int)
for i := 0; i < len(nums); i++ {
hashMap[nums[i]]++
}
arr := make([]int, 0, len(hashMap))
for key := range hashMap {
arr = append(arr, key)
}
sort.Slice(arr, func(i, j int) bool {
return hashMap[arr[i]] > hashMap[arr[j]]
})
return arr[:k]
}
Approach 2: Hash map + min-heap
Count frequencies, then keep a min-heap of size k ordered by count. Every time the heap grows past k, pop the smallest frequency. What remains are the top k frequent values.
Time: O(n + m log k) — better than full sort when k is much smaller than m.
Space: O(m + k).
package main
import "container/heap"
// item represents a (value, frequency) pair
type item struct {
val int
count int
}
// minHeap implements heap.Interface, ordered by count ascending
type minHeap []item
func (h minHeap) Len() int { return len(h) }
func (h minHeap) Less(i, j int) bool { return h[i].count < h[j].count }
func (h minHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *minHeap) Push(x interface{}) { *h = append(*h, x.(item)) }
func (h *minHeap) Pop() interface{} {
old := *h
n := len(old)
popped := old[n-1]
*h = old[:n-1]
return popped
}
func topKFrequent(nums []int, k int) []int {
// Step 1: count frequencies
freq := make(map[int]int)
for _, n := range nums {
freq[n]++
}
// Step 2: maintain a min-heap of size k
h := &minHeap{}
heap.Init(h)
for val, count := range freq {
heap.Push(h, item{val: val, count: count})
if h.Len() > k {
heap.Pop(h) // remove smallest-frequency element
}
}
// Step 3: extract results from the heap
result := make([]int, h.Len())
for i := len(result) - 1; i >= 0; i-- {
result[i] = heap.Pop(h).(item).val
}
return result
}
Which approach to use?
- Prefer hash map + sort when you want the simplest correct solution and
mis small. - Prefer hash map + min-heap when
k << mand you care about thelog kbound — a classic heap / priority-queue interview follow-up.
