Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 8507175

Browse files
feat: add solutions to lc problem: No.3672 (#4709)
1 parent 6e4118a commit 8507175

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)

AltStyle によって変換されたページ (->オリジナル) /