62
62
63
63
### 方法一:哈希表 + 优先队列(小根堆)
64
64
65
- 使用哈希表统计每个元素出现的次数,然后使用优先队列(小根堆)维护前 $k$ 个出现次数最多的元素 。
65
+ 我们可以使用一个哈希表 $\text{cnt}$ 统计每个元素出现的次数,然后使用一个小根堆(优先队列)来保存前 $k$ 个高频元素 。
66
66
67
- 时间复杂度 $O(n\log k)$。
67
+ 我们首先遍历一遍数组,统计每个元素出现的次数,然后遍历哈希表,将元素和出现次数存入小根堆中。如果小根堆的大小超过了 $k$,我们就将堆顶元素弹出,保证堆的大小始终为 $k$。
68
+
69
+ 最后,我们将小根堆中的元素依次弹出,放入结果数组中即可。
70
+
71
+ 时间复杂度 $O(n \times \log k)$,空间复杂度 $O(k)$。其中 $n$ 是数组的长度。
68
72
69
73
<!-- tabs:start -->
70
74
@@ -74,48 +78,52 @@ tags:
74
78
class Solution :
75
79
def topKFrequent (self , nums : List[int ], k : int ) -> List[int ]:
76
80
cnt = Counter(nums)
77
- return [v[ 0 ] for v in cnt.most_common(k)]
81
+ return [x for x, _ in cnt.most_common(k)]
78
82
```
79
83
80
84
#### Java
81
85
82
86
``` java
83
87
class Solution {
84
88
public int [] topKFrequent (int [] nums , int k ) {
85
- Map<Integer , Long > frequency = Arrays . stream(nums). boxed(). collect(
86
- Collectors . groupingBy(Function . identity(), Collectors . counting()));
87
- Queue<Map .Entry<Integer , Long > > queue = new PriorityQueue<> (Map . Entry . comparingByValue());
88
- for (var entry : frequency. entrySet()) {
89
- queue. offer(entry);
90
- if (queue. size() > k) {
91
- queue. poll();
89
+ Map<Integer , Integer > cnt = new HashMap<> ();
90
+ for (int x : nums) {
91
+ cnt. merge(x, 1 , Integer :: sum);
92
+ }
93
+ PriorityQueue<Map .Entry<Integer , Integer > > pq
94
+ = new PriorityQueue<> (Comparator . comparingInt(Map . Entry :: getValue));
95
+ for (var e : cnt. entrySet()) {
96
+ pq. offer(e);
97
+ if (pq. size() > k) {
98
+ pq. poll();
92
99
}
93
100
}
94
- return queue . stream(). mapToInt(Map . Entry :: getKey). toArray();
101
+ return pq . stream(). mapToInt(Map . Entry :: getKey). toArray();
95
102
}
96
103
}
97
104
```
98
105
99
106
#### C++
100
107
101
108
``` cpp
102
- using pii = pair<int , int >;
103
-
104
109
class Solution {
105
110
public:
106
111
vector<int > topKFrequent(vector<int >& nums, int k) {
107
112
unordered_map<int, int> cnt;
108
- for (int v : nums) ++cnt[ v] ;
113
+ using pii = pair<int, int>;
114
+ for (int x : nums) {
115
+ ++cnt[ x] ;
116
+ }
109
117
priority_queue<pii, vector<pii >, greater<pii >> pq;
110
- for (auto& [ num, freq ] : cnt) {
111
- pq.push({freq, num });
118
+ for (auto& [ x, c ] : cnt) {
119
+ pq.push({c, x });
112
120
if (pq.size() > k) {
113
121
pq.pop();
114
122
}
115
123
}
116
- vector<int > ans(k) ;
117
- for (int i = 0; i < k; ++i ) {
118
- ans[ i ] = pq.top().second;
124
+ vector<int > ans;
125
+ while (!pq.empty() ) {
126
+ ans.push_back( pq.top().second) ;
119
127
pq.pop();
120
128
}
121
129
return ans;
@@ -128,19 +136,19 @@ public:
128
136
```go
129
137
func topKFrequent(nums []int, k int) []int {
130
138
cnt := map[int]int{}
131
- for _, v := range nums {
132
- cnt[v ]++
139
+ for _, x := range nums {
140
+ cnt[x ]++
133
141
}
134
- h := hp{}
135
- for v, freq := range cnt {
136
- heap.Push(&h , pair{v, freq })
137
- if len(h ) > k {
138
- heap.Pop(&h )
142
+ pq := hp{}
143
+ for x, c := range cnt {
144
+ heap.Push(&pq , pair{x, c })
145
+ if pq.Len( ) > k {
146
+ heap.Pop(&pq )
139
147
}
140
148
}
141
149
ans := make([]int, k)
142
- for i := range ans {
143
- ans[i] = heap.Pop(&h ).(pair).v
150
+ for i := 0; i < k; i++ {
151
+ ans[i] = heap.Pop(&pq ).(pair).v
144
152
}
145
153
return ans
146
154
}
@@ -159,124 +167,42 @@ func (h *hp) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1];
159
167
160
168
``` ts
161
169
function topKFrequent(nums : number [], k : number ): number [] {
162
- let hashMap = new Map ();
163
- for (let num of nums ) {
164
- hashMap .set (num , (hashMap .get (num ) || 0 ) + 1 );
170
+ const cnt = new Map < number , number > ();
171
+ for (const x of nums ) {
172
+ cnt .set (x , (cnt .get (x ) ?? 0 ) + 1 );
165
173
}
166
- let list = [... hashMap ];
167
- list .sort ((a , b ) => b [1 ] - a [1 ]);
168
- let ans = [];
169
- for (let i = 0 ; i < k ; i ++ ) {
170
- ans .push (list [i ][0 ]);
174
+ const pq = new MinPriorityQueue ();
175
+ for (const [x, c] of cnt ) {
176
+ pq .enqueue (x , c );
177
+ if (pq .size () > k ) {
178
+ pq .dequeue ();
179
+ }
171
180
}
172
- return ans ;
181
+ return pq . toArray (). map ( x => x . element ) ;
173
182
}
174
183
```
175
184
176
185
#### Rust
177
186
178
187
``` rust
179
- use std :: collections :: HashMap ;
188
+ use std :: cmp :: Reverse ;
189
+ use std :: collections :: {BinaryHeap , HashMap };
190
+
180
191
impl Solution {
181
192
pub fn top_k_frequent (nums : Vec <i32 >, k : i32 ) -> Vec <i32 > {
182
- let mut map = HashMap :: new ();
183
- let mut max_count = 0 ;
184
- for & num in nums . iter () {
185
- let val = map . get (& num ). unwrap_or (& 0 ) + 1 ;
186
- map . insert (num , val );
187
- max_count = max_count . max (val );
193
+ let mut cnt = HashMap :: new ();
194
+ for x in nums {
195
+ * cnt . entry (x ). or_insert (0 ) += 1 ;
188
196
}
189
- let mut k = k as usize ;
190
- let mut res = vec! [0 ; k ];
191
- while k > 0 {
192
- let mut next = 0 ;
193
- for key in map . keys () {
194
- let val = map [key ];
195
- if val == max_count {
196
- res [k - 1 ] = * key ;
197
- k -= 1 ;
198
- } else if val < max_count {
199
- next = next . max (val );
200
- }
201
- }
202
- max_count = next ;
203
- }
204
- res
205
- }
206
- }
207
- ```
208
-
209
- <!-- tabs: end -->
210
-
211
- <!-- solution: end -->
212
-
213
- <!-- solution: start -->
214
-
215
- ### 方法二
216
-
217
- <!-- tabs: start -->
218
-
219
- #### Python3
220
-
221
- ``` python
222
- class Solution :
223
- def topKFrequent (self , nums : List[int ], k : int ) -> List[int ]:
224
- cnt = Counter(nums)
225
- hp = []
226
- for num, freq in cnt.items():
227
- heappush(hp, (freq, num))
228
- if len (hp) > k:
229
- heappop(hp)
230
- return [v[1 ] for v in hp]
231
- ```
232
-
233
- #### Java
234
-
235
- ``` java
236
- class Solution {
237
- public int [] topKFrequent (int [] nums , int k ) {
238
- Map<Integer , Integer > cnt = new HashMap<> ();
239
- for (int v : nums) {
240
- cnt. put(v, cnt. getOrDefault(v, 0 ) + 1 );
241
- }
242
- PriorityQueue<int[]> pq = new PriorityQueue<> ((a, b) - > a[1 ] - b[1 ]);
243
- for (var e : cnt. entrySet()) {
244
- pq. offer(new int [] {e. getKey(), e. getValue()});
245
- if (pq. size() > k) {
246
- pq. poll();
247
- }
248
- }
249
- int [] ans = new int [k];
250
- for (int i = 0 ; i < k; ++ i) {
251
- ans[i] = pq. poll()[0 ];
252
- }
253
- return ans;
254
- }
255
- }
256
- ```
257
-
258
- #### TypeScript
259
-
260
- ``` ts
261
- function topKFrequent(nums : number [], k : number ): number [] {
262
- const map = new Map <number , number >();
263
- let maxCount = 0 ;
264
- for (const num of nums ) {
265
- map .set (num , (map .get (num ) ?? 0 ) + 1 );
266
- maxCount = Math .max (maxCount , map .get (num ));
267
- }
268
-
269
- const res = [];
270
- while (k > 0 ) {
271
- for (const key of map .keys ()) {
272
- if (map .get (key ) === maxCount ) {
273
- res .push (key );
274
- k -- ;
197
+ let mut pq = BinaryHeap :: with_capacity (k as usize );
198
+ for (& x , & c ) in cnt . iter () {
199
+ pq . push (Reverse ((c , x )));
200
+ if pq . len () > k as usize {
201
+ pq . pop ();
275
202
}
276
203
}
277
- maxCount -- ;
204
+ pq . into_iter () . map ( | Reverse (( _ , x )) | x ) . collect ()
278
205
}
279
- return res ;
280
206
}
281
207
```
282
208
0 commit comments