Skip to content

Commit 6bb0de5

Browse files
committed
feat: add solutions to lc problem: No.3672
1 parent 6e4118a commit 6bb0de5

File tree

6 files changed

+524
-10
lines changed

6 files changed

+524
-10
lines changed

solution/3600-3699/3672.Sum of Weighted Modes in Subarrays/README.md

Lines changed: 179 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)