前 K 个高频元素
https://leetcode-cn.com/problems/top-k-frequent-elements/
快速排序
先统计元素出现频率,然后对数组进行排序。快速排序平均时间复杂度为 O(nlogn)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| func topKFrequent(nums []int, k int) []int { result := make([]int, 0) valToFreq := make(map[int]int)
for _, n := range nums { valToFreq[n]++ }
for val := range valToFreq { result = append(result, val) }
sort.Slice(result, func(i, j int) bool { return valToFreq[result[i]] > valToFreq[result[j]] })
return result[:k] }
|
堆排序:最小堆
维护一个频率的最小堆,并保持里面的元素最多只有 k 个。如果插入元素超过 k 个了,就弹出堆顶,最终留下来的就是 k 个频率最大的。由于保持了堆中元素最多为 k 个,插入和弹出的复杂度都是 O(logk),建堆时插入 n 次,总体复杂度为 O(nlogk)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| var valToFreq map[int]int
func topKFrequent(nums []int, k int) []int { result := make([]int, k) valToFreq = make(map[int]int)
for _, n := range nums { valToFreq[n]++ }
h := MaxHeap{}
for val := range valToFreq { heap.Push(&h, val) if h.Len() > k { heap.Pop(&h) } }
for i := 0; i < k; i++ { x := heap.Pop(&h).(int) result[k-1-i] = x }
return result }
type MaxHeap []int
func (h MaxHeap) Len() int { return len(h) }
func (h MaxHeap) Less(i, j int) bool { return valToFreq[h[i]] < valToFreq[h[j]] }
func (h MaxHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *MaxHeap) Push(x interface{}) { *h = append(*h, x.(int)) }
func (h *MaxHeap) Pop() interface{} { old := *h n := len(old) x := old[n-1] *h = old[:n-1] return x }
|
堆排序:最大堆
直接调包在已有元素上建立出现频率的最大堆(而不是一个一个插入),则建堆的时间复杂度只有 O(n)*,然后再弹出 k 个元素即可。每次弹出的复杂度为 O(logn),则总体复杂度为 O(klogn)。
*注:使用 Floyd 建堆算法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| var valToFreq map[int]int
func topKFrequent(nums []int, k int) []int { result := make([]int, k) valToFreq = make(map[int]int)
for _, n := range nums { valToFreq[n]++ }
h := MaxHeap{}
for val := range valToFreq { h = append(h, val) }
heap.Init(&h)
for i := 0; i < k; i++ { x := heap.Pop(&h).(int) result[i] = x }
return result }
type MaxHeap []int
func (h MaxHeap) Len() int { return len(h) }
func (h MaxHeap) Less(i, j int) bool { return valToFreq[h[i]] > valToFreq[h[j]] }
func (h MaxHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *MaxHeap) Push(x interface{}) { *h = append(*h, x.(int)) }
func (h *MaxHeap) Pop() interface{} { old := *h n := len(old) x := old[n-1] *h = old[:n-1] return x }
|