Problem Statement
Given an integer array nums and an integer k, return the k most frequent elements. You may return the answer in any order. The answer is guaranteed to be unique.
Constraints:
1 <= nums.length <= 10^5-10^4 <= nums[i] <= 10^4kis in the range[1, the number of unique elements in the array]
Follow-up: Your algorithm’s time complexity must be better than O(n log n).
My Solution (Go)
func topKFrequent(nums []int, k int) []int {
// Step 1: count each number's frequency
count := make(map[int]int)
for _, num := range nums {
count[num]++
}
// Step 2: bucket by frequency (index = frequency count)
freq := make([][]int, len(nums)+1)
for num, cnt := range count {
freq[cnt] = append(freq[cnt], num)
}
// Step 3: scan from highest freq down, collect k elements
result := []int{}
for i := len(freq) - 1; i >= 0 && len(result) < k; i-- {
result = append(result, freq[i]...)
}
return result[:k]
}Approach
Bucket sort approach:
- Count frequencies with a hash map — O(n)
- Create an array of buckets where index = frequency, value = list of numbers with that frequency
- Walk backwards from highest frequency, collecting elements until we have k
This avoids the O(n log k) heap approach entirely by exploiting the fact that frequency is bounded by array length.
Complexity
- Time: O(n)
- Space: O(n)
Notes
- The bucket array size is
len(nums)+1because the maximum possible frequency equals the array length result[:k]handles the case where the last bucket appended more elements than needed- Alternative approaches: min-heap (O(n log k)), quickselect (O(n) avg, O(n²) worst)