@@ -184,32 +184,206 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3672.Su
184
184
185
185
<!-- solution:start -->
186
186
187
- ### 方法一
187
+ ### 方法一:哈希表 + 优先队列 + 滑动窗口 + 懒删除
188
+
189
+ 我们用一个哈希表 $\textit{cnt}$ 记录当前窗口中每个数字的出现次数。我们用一个优先队列 $\textit{pq}$ 记录当前窗口中每个数字的出现次数和数字本身,优先级为出现次数从大到小,如果出现次数相同,则数字从小到大。
190
+
191
+ 我们设计一个函数 $\textit{get\_ mode()},ドル用于获取当前窗口的众数及其出现次数。具体做法是不断弹出优先队列的堆顶元素,直到堆顶元素的出现次数与哈希表中记录的出现次数相同为止,此时堆顶元素即为当前窗口的众数及其出现次数。
192
+
193
+ 我们用一个变量 $\textit{ans}$ 记录所有窗口的权重和。初始时,我们将数组的前 $k$ 个数字加入哈希表和优先队列中,然后调用 $\textit{get\_ mode()}$ 获取第一个窗口的众数及其出现次数,并将其权重加入 $\textit{ans}$。
194
+
195
+ 然后,我们从数组的第 $k$ 个数字开始,依次将每个数字加入哈希表和优先队列中,同时将窗口的左端数字从哈希表中删除(出现次数减一)。然后调用 $\textit{get\_ mode()}$ 获取当前窗口的众数及其出现次数,并将其权重加入 $\textit{ans}$。
196
+
197
+ 最后,返回 $\textit{ans}$。
198
+
199
+ 时间复杂度 $O(n \log k),ドル其中 $n$ 是数组的长度。空间复杂度 $O(k)$。
188
200
189
201
<!-- tabs:start -->
190
202
191
203
#### Python3
192
204
193
205
``` python
194
-
206
+ class Solution :
207
+ def modeWeight (self , nums : List[int ], k : int ) -> int :
208
+ pq = []
209
+ cnt = defaultdict(int )
210
+ for x in nums[:k]:
211
+ cnt[x] += 1
212
+ heappush(pq, (- cnt[x], x))
213
+
214
+ def get_mode () -> int :
215
+ while - pq[0 ][0 ] != cnt[pq[0 ][1 ]]:
216
+ heappop(pq)
217
+ freq, val = - pq[0 ][0 ], pq[0 ][1 ]
218
+ return freq * val
219
+
220
+ ans = 0
221
+ ans += get_mode()
222
+
223
+ for i in range (k, len (nums)):
224
+ x, y = nums[i], nums[i - k]
225
+ cnt[x] += 1
226
+ cnt[y] -= 1
227
+ heappush(pq, (- cnt[x], x))
228
+ heappush(pq, (- cnt[y], y))
229
+
230
+ ans += get_mode()
231
+
232
+ return ans
195
233
```
196
234
197
235
#### Java
198
236
199
237
``` java
200
-
238
+ class Solution {
239
+ public long modeWeight (int [] nums , int k ) {
240
+ Map<Integer , Integer > cnt = new HashMap<> ();
241
+ PriorityQueue<int[]> pq = new PriorityQueue<> (
242
+ (a, b) - > a[0 ] != b[0 ] ? Integer . compare(a[0 ], b[0 ]) : Integer . compare(a[1 ], b[1 ]));
243
+
244
+ for (int i = 0 ; i < k; i++ ) {
245
+ int x = nums[i];
246
+ cnt. merge(x, 1 , Integer :: sum);
247
+ pq. offer(new int [] {- cnt. get(x), x});
248
+ }
249
+
250
+ long ans = 0 ;
251
+
252
+ Supplier<Long > getMode = () - > {
253
+ while (true ) {
254
+ int [] top = pq. peek();
255
+ int val = top[1 ];
256
+ int freq = - top[0 ];
257
+ if (cnt. getOrDefault(val, 0 ) == freq) {
258
+ return 1L * freq * val;
259
+ }
260
+ pq. poll();
261
+ }
262
+ };
263
+
264
+ ans += getMode. get();
265
+
266
+ for (int i = k; i < nums. length; i++ ) {
267
+ int x = nums[i], y = nums[i - k];
268
+ cnt. merge(x, 1 , Integer :: sum);
269
+ pq. offer(new int [] {- cnt. get(x), x});
270
+ cnt. merge(y, - 1 , Integer :: sum);
271
+ pq. offer(new int [] {- cnt. get(y), y});
272
+ ans += getMode. get();
273
+ }
274
+
275
+ return ans;
276
+ }
277
+ }
201
278
```
202
279
203
280
#### C++
204
281
205
282
``` cpp
206
-
283
+ class Solution {
284
+ public:
285
+ long long modeWeight(vector<int >& nums, int k) {
286
+ unordered_map<int, int> cnt;
287
+ priority_queue<pair<int, int>> pq; // {freq, -val}
288
+
289
+ for (int i = 0; i < k; i++) {
290
+ int x = nums[i];
291
+ cnt[x]++;
292
+ pq.push({cnt[x], -x});
293
+ }
294
+
295
+ auto get_mode = [&]() {
296
+ while (true) {
297
+ auto [freq, negVal] = pq.top();
298
+ int val = -negVal;
299
+ if (cnt[val] == freq) {
300
+ return 1LL * freq * val;
301
+ }
302
+ pq.pop();
303
+ }
304
+ };
305
+
306
+ long long ans = 0;
307
+ ans += get_mode();
308
+
309
+ for (int i = k; i < nums.size(); i++) {
310
+ int x = nums[i], y = nums[i - k];
311
+ cnt[x]++;
312
+ cnt[y]--;
313
+ pq.push({cnt[x], -x});
314
+ pq.push({cnt[y], -y});
315
+ ans += get_mode();
316
+ }
317
+
318
+ return ans;
319
+ }
320
+ };
207
321
```
208
322
209
323
#### Go
210
324
211
325
``` go
212
-
326
+ func modeWeight (nums []int , k int ) int64 {
327
+ cnt := make (map [int ]int )
328
+ pq := &MaxHeap{}
329
+ heap.Init (pq)
330
+
331
+ for i := 0 ; i < k; i++ {
332
+ x := nums[i]
333
+ cnt[x]++
334
+ heap.Push (pq, pair{cnt[x], x})
335
+ }
336
+
337
+ getMode := func () int64 {
338
+ for {
339
+ top := (*pq)[0 ]
340
+ if cnt[top.val ] == top.freq {
341
+ return int64 (top.freq ) * int64 (top.val )
342
+ }
343
+ heap.Pop (pq)
344
+ }
345
+ }
346
+
347
+ var ans int64
348
+ ans += getMode ()
349
+
350
+ for i := k; i < len (nums); i++ {
351
+ x , y := nums[i], nums[i-k]
352
+ cnt[x]++
353
+ cnt[y]--
354
+ heap.Push (pq, pair{cnt[x], x})
355
+ heap.Push (pq, pair{cnt[y], y})
356
+ ans += getMode ()
357
+ }
358
+
359
+ return ans
360
+ }
361
+
362
+ type pair struct {
363
+ freq int
364
+ val int
365
+ }
366
+
367
+ type MaxHeap []pair
368
+
369
+ func (h MaxHeap ) Len () int { return len (h) }
370
+ func (h MaxHeap ) Less (i , j int ) bool {
371
+ if h[i].freq != h[j].freq {
372
+ return h[i].freq > h[j].freq
373
+ }
374
+ return h[i].val < h[j].val
375
+ }
376
+ func (h MaxHeap ) Swap (i , j int ) { h[i], h[j] = h[j], h[i] }
377
+ func (h *MaxHeap ) Push (x any ) {
378
+ *h = append (*h, x.(pair))
379
+ }
380
+ func (h *MaxHeap ) Pop () any {
381
+ old := *h
382
+ n := len (old)
383
+ x := old[n-1 ]
384
+ *h = old[:n-1 ]
385
+ return x
386
+ }
213
387
```
214
388
215
389
<!-- tabs:end -->
0 commit comments