Skip to content

Commit 1935e56

Browse files
committed
✨feat: Add 1606
1 parent db4b67d commit 1935e56

6 files changed

+136
-2
lines changed

Index/哈希表.md

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
| [1600. 皇位继承顺序](https://leetcode-cn.com/problems/throne-inheritance/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/throne-inheritance/solution/gong-shui-san-xie-shi-yong-dan-xiang-lia-7t65/) | 中等 | 🤩🤩🤩 |
5454
| [1603. 设计停车系统](https://leetcode-cn.com/problems/design-parking-system/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/design-parking-system/solution/yi-ti-san-jie-jian-dan-bian-liang-ha-xi-0gs72/) | 简单 | 🤩🤩 |
5555
| [1711. 大餐计数](https://leetcode-cn.com/problems/count-good-meals/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/count-good-meals/solution/gong-shui-san-xie-xiang-jie-san-chong-gu-nn4f/) | 中等 | 🤩🤩🤩 |
56+
| [1606. 找到处理最多请求的服务器](https://leetcode-cn.com/problems/find-servers-that-handled-most-number-of-requests/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-servers-that-handled-most-number-of-requests/solution/by-ac_oier-zgm6/) | 困难 | 🤩🤩🤩🤩 |
5657
| [1743. 从相邻元素对还原数组](https://leetcode-cn.com/problems/restore-the-array-from-adjacent-pairs/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/restore-the-array-from-adjacent-pairs/solution/gong-shui-san-xie-yi-ti-shuang-jie-dan-x-elpx/) | 中等 | 🤩🤩🤩🤩 |
5758
| [1748. 唯一元素的和](https://leetcode-cn.com/problems/sum-of-unique-elements/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/sum-of-unique-elements/solution/gong-shui-san-xie-yi-ti-shuang-jie-pai-x-atnd/) | 简单 | 🤩🤩🤩🤩 |
5859
| [1838. 最高频元素的频数](https://leetcode-cn.com/problems/frequency-of-the-most-frequent-element/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/frequency-of-the-most-frequent-element/solution/gong-shui-san-xie-cong-mei-ju-dao-pai-xu-kxnk/) | 中等 | 🤩🤩🤩 |

Index/堆.md

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
| [1005. K 次取反后最大化的数组和](https://leetcode-cn.com/problems/maximize-sum-of-array-after-k-negations/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximize-sum-of-array-after-k-negations/solution/gong-shui-san-xie-jian-dan-fen-qing-kuan-6qwu/) | 简单 | 🤩🤩🤩🤩 |
2121
| [1337. 矩阵中战斗力最弱的 K 行](https://leetcode-cn.com/problems/the-k-weakest-rows-in-a-matrix/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/the-k-weakest-rows-in-a-matrix/solution/gong-shui-san-xie-yi-ti-shuang-jie-po-su-7okx/) | 简单 | 🤩🤩🤩 |
2222
| [1405. 最长快乐字符串](https://leetcode-cn.com/problems/longest-happy-string/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/longest-happy-string/solution/gong-shui-san-xie-jie-he-you-xian-dui-li-q6fd/) | 中等 | 🤩🤩🤩🤩 |
23+
| [1606. 找到处理最多请求的服务器](https://leetcode-cn.com/problems/find-servers-that-handled-most-number-of-requests/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-servers-that-handled-most-number-of-requests/solution/by-ac_oier-zgm6/) | 困难 | 🤩🤩🤩🤩 |
2324
| [1705. 吃苹果的最大数目](https://leetcode-cn.com/problems/maximum-number-of-eaten-apples/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximum-number-of-eaten-apples/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-hfdy0/) | 中等 | 🤩🤩🤩🤩🤩 |
2425
| [1834. 单线程 CPU](https://leetcode-cn.com/problems/single-threaded-cpu/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/single-threaded-cpu/solution/gong-shui-san-xie-shu-ju-jie-gou-yun-yon-1qk0/) | 中等 | 🤩🤩🤩🤩 |
2526
| [面试题 17.14. 最小K个数](https://leetcode-cn.com/problems/smallest-k-lcci/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/smallest-k-lcci/solution/gong-shui-san-xie-yi-ti-si-jie-you-xian-yy5k5/) | 中等 | 🤩🤩🤩🤩 |

Index/模拟.md

+1
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
| [1518. 换酒问题](https://leetcode-cn.com/problems/water-bottles/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/water-bottles/solution/gong-shui-san-xie-yi-ti-shuang-jie-ji-sh-7yyo/) | 简单 | 🤩🤩🤩🤩 |
107107
| [1576. 替换所有的问号](https://leetcode-cn.com/problems/replace-all-s-to-avoid-consecutive-repeating-characters/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/replace-all-s-to-avoid-consecutive-repeating-characters/solution/gong-shui-san-xie-jian-dan-zi-fu-chuan-m-fa1u/) | 简单 | 🤩🤩🤩🤩🤩 |
108108
| [1583. 统计不开心的朋友](https://leetcode-cn.com/problems/count-unhappy-friends/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/count-unhappy-friends/solution/gong-shui-san-xie-ha-xi-biao-mo-ni-ti-by-2qy0/) | 中等 | 🤩🤩🤩🤩 |
109+
| [1606. 找到处理最多请求的服务器](https://leetcode-cn.com/problems/find-servers-that-handled-most-number-of-requests/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-servers-that-handled-most-number-of-requests/solution/by-ac_oier-zgm6/) | 困难 | 🤩🤩🤩🤩 |
109110
| [1614. 括号的最大嵌套深度](https://leetcode-cn.com/problems/maximum-nesting-depth-of-the-parentheses/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximum-nesting-depth-of-the-parentheses/solution/gong-shui-san-xie-jian-dan-mo-ni-ti-by-a-pf5d/) | 简单 | 🤩🤩🤩🤩🤩 |
110111
| [1629. 按键持续时间最长的键](https://leetcode-cn.com/problems/slowest-key/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/slowest-key/solution/gong-shui-san-xie-jian-dan-mo-ni-ti-by-a-zjwb/) | 简单 | 🤩🤩🤩🤩🤩 |
111112
| [1646. 获取生成数组中的最大值](https://leetcode-cn.com/problems/get-maximum-in-generated-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/get-maximum-in-generated-array/solution/gong-shui-san-xie-jian-dan-mo-ni-ti-by-a-sj53/) | 简单 | 🤩🤩🤩🤩 |

Index/红黑树.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
| 题目 | 题解 | 难度 | 推荐指数 |
22
| ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | -------- |
3+
| [1606. 找到处理最多请求的服务器](https://leetcode-cn.com/problems/find-servers-that-handled-most-number-of-requests/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-servers-that-handled-most-number-of-requests/solution/by-ac_oier-zgm6/) | 困难 | 🤩🤩🤩🤩 |
34
| [2034. 股票价格波动](https://leetcode-cn.com/problems/stock-price-fluctuation/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/stock-price-fluctuation/solution/gong-shui-san-xie-shu-ju-jie-gou-mo-ni-t-u6f4/) | 中等 | 🤩🤩🤩🤩 |
45

LeetCode/1001-1010/1004. 最大连续1的个数 III(中等).md

+1-2
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ Tag : 「双指针」、「滑动窗口」、「二分」、「前缀和」
5555
class Solution {
5656
public int longestOnes(int[] nums, int k) {
5757
int n = nums.length;
58-
//
5958
int[][] f = new int[2][k + 1];
6059
int ans = 0;
6160
for (int i = 1; i <= n; i++) {
@@ -98,7 +97,7 @@ class Solution {
9897
**因此,对于某个确定的「左端点/右端点」而言,以「其最远右端点/最远左端点」为分割点的前缀和数轴,具有「二段性」。可以通过二分来找分割点。**
9998

10099
代码:
101-
```Java []
100+
```Java
102101
class Solution {
103102
public int longestOnes(int[] nums, int k) {
104103
int n = nums.length;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[1606. 找到处理最多请求的服务器](https://leetcode-cn.com/problems/find-servers-that-handled-most-number-of-requests/solution/by-ac_oier-zgm6/)** ,难度为 **困难**
4+
5+
Tag : 「数据结构」、「优先队列」、「堆」、「红黑树」、「二分」
6+
7+
8+
9+
你有 $k$ 个服务器,编号为 $0$ 到 $k-1$ ,它们可以同时处理多个请求组。
10+
11+
每个服务器有无穷的计算能力但是不能同时处理超过一个请求。
12+
13+
请求分配到服务器的规则如下:
14+
* 第 $i$(序号从 $0$ 开始)个请求到达。
15+
* 如果所有服务器都已被占据,那么该请求被舍弃(完全不处理)。
16+
* 如果第 ( `i % k` ) 个服务器空闲,那么对应服务器会处理该请求。
17+
* 否则,将请求安排给下一个空闲的服务器(服务器构成一个环,必要的话可能从第 $0$ 个服务器开始继续找下一个空闲的服务器)。比方说,如果第 $i$ 个服务器在忙,那么会查看第 ( $i+1$ ) 个服务器,第 ( $i+2$ ) 个服务器等等。
18+
* 给你一个严格递增的正整数数组 `arrival`,表示第 $i$ 个任务的到达时间,和另一个数组 `load` ,其中 $load[i]$ 表示第 $i$ 个请求的工作量(也就是服务器完成它所需要的时间)。你的任务是找到 最繁忙的服务器 。最繁忙定义为一个服务器处理的请求数是所有服务器里最多的。
19+
20+
请你返回包含所有最繁忙服务器序号的列表,你可以以任意顺序返回这个列表。
21+
22+
示例 1:
23+
![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2020/10/03/load-1.png)
24+
25+
```
26+
输入:k = 3, arrival = [1,2,3,4,5], load = [5,2,3,3,3]
27+
28+
输出:[1]
29+
30+
解释:
31+
所有服务器一开始都是空闲的。
32+
前 3 个请求分别由前 3 台服务器依次处理。
33+
请求 3 进来的时候,服务器 0 被占据,所以它呗安排到下一台空闲的服务器,也就是服务器 1 。
34+
请求 4 进来的时候,由于所有服务器都被占据,该请求被舍弃。
35+
服务器 0 和 2 分别都处理了一个请求,服务器 1 处理了两个请求。所以服务器 1 是最忙的服务器。
36+
```
37+
示例 2:
38+
```
39+
输入:k = 3, arrival = [1,2,3,4], load = [1,2,1,2]
40+
41+
输出:[0]
42+
43+
解释:
44+
前 3 个请求分别被前 3 个服务器处理。
45+
请求 3 进来,由于服务器 0 空闲,它被服务器 0 处理。
46+
服务器 0 处理了两个请求,服务器 1 和 2 分别处理了一个请求。所以服务器 0 是最忙的服务器。
47+
```
48+
示例 3:
49+
```
50+
输入:k = 3, arrival = [1,2,3], load = [10,12,11]
51+
52+
输出:[0,1,2]
53+
54+
解释:每个服务器分别处理了一个请求,所以它们都是最忙的服务器。
55+
```
56+
示例 4:
57+
```
58+
输入:k = 3, arrival = [1,2,3,4,8,9,10], load = [5,2,10,3,1,2,2]
59+
60+
输出:[1]
61+
```
62+
示例 5:
63+
```
64+
输入:k = 1, arrival = [1], load = [1]
65+
66+
输出:[0]
67+
```
68+
69+
提示:
70+
* $1 <= k <= 10^5$
71+
* $1 <= arrival.length, load.length <= 10^5$
72+
* $arrival.length == load.length$
73+
* $1 <= arrival[i], load[i] <= 10^9$
74+
* `arrival` 保证严格递增。
75+
76+
---
77+
78+
### 数据结构
79+
80+
题目要统计处理任务数最多的机器,首先容易想到使用「哈希表」统计每个机台处理的任务数,利用机台数量 $k$ 最多不超过 $10^5$,我们可以开一个静态数组 `cnts` 来充当哈希表,同时维护一个当前处理的最大任务数量 `max`,最终所有满足 $cnst[i] = \max$ 的机台集合即是答案。
81+
82+
再根据「每个任务有对应的开始时间和持续时间」以及「任务分配规则」,容易想到使用优先队列(堆)和有序集合(红黑树)来进行维护。
83+
84+
具体的,利用「每个任务有对应的开始时间和持续时间」,我们使用优先队列(堆)维护二元组 $(idx, endTime)$,其中 $idx$ 为机器编号,$endTime$ 为当前机台所处理任务的结束时间(也就是该机台最早能够接受新任务的时刻),对于每个 $arrival[i]$ 而言(新任务),我们先从优先队列中取出所有 $endTime < arrival[i]$ 的机台 $idx$,加入「空闲池」,然后再按照「任务分配规则」从空闲池子中取机台,若取不到,则丢弃该任务。
85+
86+
由于「任务分配规则」是优先取大于等于 `i % k` 的最小值,若取不到,再取大于等于 $0$ 的最小值。因此我们的「空闲池」最好是支持「二分」的有序集合,容易想到基于「红黑树」的 `TreeSet` 结构。
87+
88+
代码:
89+
```Java
90+
class Solution {
91+
static int N = 100010;
92+
static int[] cnts = new int[N];
93+
public List<Integer> busiestServers(int k, int[] arrival, int[] load) {
94+
Arrays.fill(cnts, 0);
95+
int n = arrival.length, max = 0;
96+
PriorityQueue<int[]> busy = new PriorityQueue<>((a,b)->a[1]-b[1]);
97+
TreeSet<Integer> free = new TreeSet<>();
98+
for (int i = 0; i < k; i++) free.add(i);
99+
for (int i = 0; i < n; i++) {
100+
int start = arrival[i], end = start + load[i];
101+
while (!busy.isEmpty() && busy.peek()[1] <= start) free.add(busy.poll()[0]);
102+
Integer u = free.ceiling(i % k);
103+
if (u == null) u = free.ceiling(0);
104+
if (u == null) continue;
105+
free.remove(u);
106+
busy.add(new int[]{u, end});
107+
max = Math.max(max, ++cnts[u]);
108+
}
109+
List<Integer> ans = new ArrayList<>();
110+
for (int i = 0; i < k; i++) {
111+
if (cnts[i] == max) ans.add(i);
112+
}
113+
return ans;
114+
}
115+
}
116+
```
117+
* 时间复杂度:令任务数量为 $n$,机台数量为 $k$,起始将所有机台存入 `TreeSet`,复杂度为 $O(k\log{k})$;每次处理新的 $arrival[i]$ 时,先从优先队列取出可接受新任务的机台,存入 `TreeSet`,然后从 `TreeSet` 中取出最多一个的机台来完成任务,其中从 `TreeSet` 中取出机台最多调用两次的 `ceiling` 操作,复杂度为 $O(\log{k})$,这部分的整体复杂度为 $O(n\log{k})$;统计处理任务数达到 `max` 的机台集合复杂度为 $O(k)$;整体复杂度为 $O((k + n)\log{k})$
118+
* 空间复杂度:$O(k)$
119+
120+
---
121+
122+
### 最后
123+
124+
这是我们「刷穿 LeetCode」系列文章的第 `No.1606` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
125+
126+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
127+
128+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
129+
130+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
131+

0 commit comments

Comments
 (0)