-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtop_k_elem.go
129 lines (108 loc) · 2.29 KB
/
top_k_elem.go
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package problem0347
import (
"container/heap"
"sort"
)
/*
Given an integer array nums and an integer k, return the k most frequent elements.
You may return the answer in any order.
*/
func topKFrequentSort(nums []int, k int) []int {
var freq = map[int]int{}
var res []int
// Calculate frequencies
for i := range nums {
if _, ok := freq[nums[i]]; !ok {
res = append(res, nums[i])
}
freq[nums[i]]++
}
// Sort by frequency descending
sort.Slice(res, func(i, j int) bool {
return freq[nums[i]] > freq[nums[j]]
})
// Get 5 biggest items
return res[:k]
}
func topKFrequentBucket(nums []int, k int) []int {
var freq = map[int]int{}
var res = make([]int, k)
var buckets [][]int
var maxFreq int
// Calculate frequencies
for i := range nums {
freq[nums[i]]++
maxFreq = max(maxFreq, freq[nums[i]])
}
// Build buckets
buckets = make([][]int, maxFreq)
for key, val := range freq {
buckets[val-1] = append(buckets[val-1], key)
}
// Getting res
var idx = len(buckets) - 1
for i := range res {
for len(buckets[idx]) == 0 {
idx--
}
res[i] = buckets[idx][len(buckets[idx])-1]
buckets[idx] = buckets[idx][:len(buckets[idx])-1]
}
return res
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func topKFrequentHeap(nums []int, k int) []int {
var freq = map[int]int{}
var res []int
// Calculate frequencies
for i := range nums {
freq[nums[i]]++
}
h := &FreqHeap{}
var i int
// Add frequencies to heap
for key, val := range freq {
if i < k {
// Add initial k items
heap.Push(h, [2]int{val, key})
} else if val > (*h)[0][0] {
// If current item bigger than the smallest
// item in the heap, pop the smallest, add the new one
heap.Pop(h)
heap.Push(h, [2]int{val, key})
}
i++
}
// Move items from heap to res
res = make([]int, k)
for i := k - 1; i >= 0; i-- {
res[i] = heap.Pop(h).([2]int)[1]
}
return res
}
// Implementation of a min-heap for integers
type FreqHeap [][2]int
func (h FreqHeap) Len() int {
return len(h)
}
func (h FreqHeap) Less(i, j int) bool {
return h[i][0] < h[j][0]
}
func (h FreqHeap) Swap(i, j int) {
h[i], h[j] = h[j], h[i]
}
func (h *FreqHeap) Push(x interface{}) {
*h = append(*h, x.([2]int))
}
func (h *FreqHeap) Pop() interface{} {
old := *h
n := len(old)
x := old[n-1]
*h = old[:n-1]
return x
}