Skip to content

Commit 26f4347

Browse files
authored
feat: add solutions for lc No.3851 (#5045)
1 parent f85dbb9 commit 26f4347

12 files changed

Lines changed: 692 additions & 3 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
- [乘积小于 K 的子数组](/solution/0700-0799/0713.Subarray%20Product%20Less%20Than%20K/README.md) - `双指针`
5353
- [位 1 的个数](/solution/0100-0199/0191.Number%20of%201%20Bits/README.md) - `位运算``lowbit`
5454
- [合并区间](/solution/0000-0099/0056.Merge%20Intervals/README.md) - `区间合并`
55-
<!-- 排序算法、待补充 -->
55+
<!-- 排序算法、待补充 -->
5656

5757
### 2. 数据结构
5858

solution/1000-1099/1022.Sum of Root To Leaf Binary Numbers/Solution.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ def dfs(root: Optional[TreeNode], x: int) -> int:
1313
if root.left == root.right:
1414
return x
1515
return dfs(root.left, x) + dfs(root.right, x)
16-
16+
1717
return dfs(root, 0)
Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
---
2+
comments: true
3+
difficulty: 中等
4+
edit_url: https://github.com/doocs/leetcode/edit/main/solution/3800-3899/3851.Maximum%20Requests%20Without%20Violating%20the%20Limit/README.md
5+
---
6+
7+
<!-- problem:start -->
8+
9+
# [3851. Maximum Requests Without Violating the Limit 🔒](https://leetcode.cn/problems/maximum-requests-without-violating-the-limit)
10+
11+
[English Version](/solution/3800-3899/3851.Maximum%20Requests%20Without%20Violating%20the%20Limit/README_EN.md)
12+
13+
## 题目描述
14+
15+
<!-- description:start -->
16+
17+
<p>You are given a 2D integer array <code>requests</code>, where <code>requests[i] = [user<sub>i</sub>, time<sub>i</sub>]</code> indicates that <code>user<sub>i</sub></code> made a request at <code>time<sub>i</sub></code>.</p>
18+
19+
<p>You are also given two integers <code>k</code> and <code>window</code>.</p>
20+
21+
<p>A user violates the limit if there exists an integer <code>t</code> such that the user makes strictly more than <code>k</code> requests in the inclusive interval <code>[t, t + window]</code>.</p>
22+
23+
<p>You may drop any number of requests.</p>
24+
25+
<p>Return an integer denoting the <strong>maximum</strong>​​​​​​​ number of requests that can <strong>remain</strong> such that no user violates the limit.</p>
26+
27+
<p>&nbsp;</p>
28+
<p><strong class="example">Example 1:</strong></p>
29+
30+
<div class="example-block">
31+
<p><strong>Input:</strong> <span class="example-io">requests = [[1,1],[2,1],[1,7],[2,8]], k = 1, window = 4</span></p>
32+
33+
<p><strong>Output:</strong> <span class="example-io">4</span></p>
34+
35+
<p><strong>Explanation:</strong>​​​​​​​</p>
36+
37+
<ul>
38+
<li>For user 1, the request times are <code>[1, 7]</code>. The difference between them is 6, which is greater than <code>window = 4</code>.</li>
39+
<li>For user 2, the request times are <code>[1, 8]</code>. The difference is 7, which is also greater than <code>window = 4</code>.</li>
40+
<li>No user makes more than <code>k = 1</code> request within any inclusive interval of length <code>window</code>. Therefore, all 4 requests can remain.</li>
41+
</ul>
42+
</div>
43+
44+
<p><strong class="example">Example 2:</strong></p>
45+
46+
<div class="example-block">
47+
<p><strong>Input:</strong> <span class="example-io">requests = [[1,2],[1,5],[1,2],[1,6]], k = 2, window = 5</span></p>
48+
49+
<p><strong>Output:</strong> <span class="example-io">2</span></p>
50+
51+
<p><strong>Explanation:</strong>​​​​​​​</p>
52+
53+
<ul>
54+
<li>For user 1, the request times are <code>[2, 2, 5, 6]</code>. The inclusive interval <code>[2, 7]</code> of length <code>window = 5</code> contains all 4 requests.</li>
55+
<li>Since 4 is strictly greater than <code>k = 2</code>, at least 2 requests must be removed.</li>
56+
<li>After removing any 2 requests, every inclusive interval of length <code>window</code> contains at most <code>k = 2</code> requests.</li>
57+
<li>Therefore, the maximum number of requests that can remain is 2.</li>
58+
</ul>
59+
</div>
60+
61+
<p><strong class="example">Example 3:</strong></p>
62+
63+
<div class="example-block">
64+
<p><strong>Input:</strong> <span class="example-io">requests = [[1,1],[2,5],[1,2],[3,9]], k = 1, window = 1</span></p>
65+
66+
<p><strong>Output:</strong> <span class="example-io">3</span></p>
67+
68+
<p><strong>Explanation:</strong></p>
69+
70+
<ul>
71+
<li>For user 1, the request times are <code>[1, 2]</code>. The difference is 1, which is equal to <code>window = 1</code>.</li>
72+
<li>The inclusive interval <code>[1, 2]</code> contains both requests, so the count is 2, which exceeds <code>k = 1</code>. One request must be removed.</li>
73+
<li>Users 2 and 3 each have only one request and do not violate the limit. Therefore, the maximum number of requests that can remain is 3.</li>
74+
</ul>
75+
</div>
76+
77+
<p>&nbsp;</p>
78+
<p><strong>Constraints:</strong></p>
79+
80+
<ul>
81+
<li><code>1 &lt;= requests.length &lt;= 10<sup>5</sup></code></li>
82+
<li><code>requests[i] = [user<sub>i</sub>, time<sub>i</sub>]</code></li>
83+
<li><code>1 &lt;= k &lt;= requests.length</code></li>
84+
<li><code>1 &lt;= user<sub>i</sub>, time<sub>i</sub>, window &lt;= 10<sup>5</sup></code></li>
85+
</ul>
86+
87+
<!-- description:end -->
88+
89+
## 解法
90+
91+
<!-- solution:start -->
92+
93+
### 方法一:滑动窗口 + 双端队列
94+
95+
我们可以将请求按照用户进行分组,放在哈希表 $g$ 中,其中 $g[u]$ 是用户 $u$ 的请求时间列表。对于每个用户,我们需要从请求时间列表中删除一些请求,使得在任意长度为 $window$ 的区间内,剩余的请求数不超过 $k$。
96+
97+
对于用户 $u$ 的请求时间列表 $g[u]$,我们首先对其进行排序。然后,我们使用一个双端队列 $kept$ 来维护当前保留的请求时间。我们遍历请求时间列表中的每个请求时间 $t$,对于每个请求时间,我们需要将 $kept$ 中所有与 $t$ 的差值大于 $window$ 的请求时间删除掉。然后,我们将 $t$ 添加到 $kept$ 中。如果此时 $kept$ 中的请求数超过了 $k$,我们需要删除掉 $kept$ 中的最后一个请求时间,并增加删除的请求数。最后,我们将用户 $u$ 的请求数减去删除的请求数,累加到答案中。
98+
99+
时间复杂度 $O(n \log n)$,空间复杂度 $O(n)$,其中 $n$ 是请求的数量。每个请求被访问一次,排序需要 $O(n \log n)$ 的时间,哈希表和双端队列的操作需要 $O(n)$ 的时间。
100+
101+
<!-- tabs:start -->
102+
103+
#### Python3
104+
105+
```python
106+
class Solution:
107+
def maxRequests(self, requests: list[list[int]], k: int, window: int) -> int:
108+
g = defaultdict(list)
109+
for u, t in requests:
110+
g[u].append(t)
111+
ans = 0
112+
for ts in g.values():
113+
ts.sort()
114+
kept = deque()
115+
deletions = 0
116+
for t in ts:
117+
while kept and t - kept[0] > window:
118+
kept.popleft()
119+
kept.append(t)
120+
if len(kept) > k:
121+
kept.pop()
122+
deletions += 1
123+
ans += len(ts) - deletions
124+
return ans
125+
```
126+
127+
#### Java
128+
129+
```java
130+
class Solution {
131+
public int maxRequests(int[][] requests, int k, int window) {
132+
Map<Integer, List<Integer>> g = new HashMap<>();
133+
for (int[] r : requests) {
134+
int u = r[0], t = r[1];
135+
g.computeIfAbsent(u, x -> new ArrayList<>()).add(t);
136+
}
137+
138+
int ans = 0;
139+
ArrayDeque<Integer> kept = new ArrayDeque<>();
140+
141+
for (List<Integer> ts : g.values()) {
142+
Collections.sort(ts);
143+
kept.clear();
144+
int deletions = 0;
145+
146+
for (int t : ts) {
147+
while (!kept.isEmpty() && t - kept.peekFirst() > window) {
148+
kept.pollFirst();
149+
}
150+
kept.addLast(t);
151+
if (kept.size() > k) {
152+
kept.pollLast();
153+
deletions++;
154+
}
155+
}
156+
ans += ts.size() - deletions;
157+
}
158+
return ans;
159+
}
160+
}
161+
```
162+
163+
#### C++
164+
165+
```cpp
166+
class Solution {
167+
public:
168+
int maxRequests(vector<vector<int>>& requests, int k, int window) {
169+
unordered_map<int, vector<int>> g;
170+
g.reserve(requests.size() * 2);
171+
172+
for (auto& r : requests) {
173+
g[r[0]].push_back(r[1]);
174+
}
175+
176+
int ans = 0;
177+
deque<int> kept;
178+
179+
for (auto& [_, ts] : g) {
180+
sort(ts.begin(), ts.end());
181+
kept.clear();
182+
int deletions = 0;
183+
184+
for (int t : ts) {
185+
while (!kept.empty() && t - kept.front() > window) {
186+
kept.pop_front();
187+
}
188+
kept.push_back(t);
189+
if (kept.size() > k) {
190+
kept.pop_back();
191+
deletions++;
192+
}
193+
}
194+
ans += ts.size() - deletions;
195+
}
196+
return ans;
197+
}
198+
};
199+
```
200+
201+
#### Go
202+
203+
```go
204+
func maxRequests(requests [][]int, k int, window int) (ans int) {
205+
g := make(map[int][]int)
206+
for _, r := range requests {
207+
u, t := r[0], r[1]
208+
g[u] = append(g[u], t)
209+
}
210+
for _, ts := range g {
211+
sort.Ints(ts)
212+
213+
kept := make([]int, 0)
214+
head := 0
215+
deletions := 0
216+
217+
for _, t := range ts {
218+
for head < len(kept) && t-kept[head] > window {
219+
head++
220+
}
221+
kept = append(kept, t)
222+
if len(kept)-head > k {
223+
kept = kept[:len(kept)-1]
224+
deletions++
225+
}
226+
}
227+
228+
ans += len(ts) - deletions
229+
}
230+
return
231+
}
232+
```
233+
234+
#### TypeScript
235+
236+
```ts
237+
function maxRequests(requests: number[][], k: number, window: number): number {
238+
const g = new Map<number, number[]>();
239+
for (const [u, t] of requests) {
240+
if (!g.has(u)) g.set(u, []);
241+
g.get(u)!.push(t);
242+
}
243+
244+
let ans = 0;
245+
246+
for (const ts of g.values()) {
247+
ts.sort((a, b) => a - b);
248+
249+
const kept: number[] = [];
250+
let head = 0;
251+
let deletions = 0;
252+
253+
for (const t of ts) {
254+
while (head < kept.length && t - kept[head] > window) head++;
255+
kept.push(t);
256+
if (kept.length - head > k) {
257+
kept.pop();
258+
deletions++;
259+
}
260+
}
261+
262+
ans += ts.length - deletions;
263+
}
264+
265+
return ans;
266+
}
267+
```
268+
269+
<!-- tabs:end -->
270+
271+
<!-- solution:end -->
272+
273+
<!-- problem:end -->

0 commit comments

Comments
 (0)