@@ -184,32 +184,206 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3672.Su
184184
185185<!-- solution:start -->
186186
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)$。
188200
189201<!-- tabs:start -->
190202
191203#### Python3
192204
193205``` 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
195233```
196234
197235#### Java
198236
199237``` 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+ }
201278```
202279
203280#### C++
204281
205282``` 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+ };
207321```
208322
209323#### Go
210324
211325``` 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+ }
213387```
214388
215389<!-- tabs:end -->
0 commit comments