Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Tag : 「数据结构」、「优先队列」、「堆」、「红黑树」、

再根据「每个任务有对应的开始时间和持续时间」以及「任务分配规则」,容易想到使用优先队列(堆)和有序集合(红黑树)来进行维护。

具体的,利用「每个任务有对应的开始时间和持续时间」,我们使用优先队列(堆)维护二元组 $(idx, endTime)$,其中 $idx$ 为机器编号,$endTime$ 为当前机台所处理任务的结束时间(也就是该机台最早能够接受新任务的时刻),对于每个 $arrival[i]$ 而言(新任务),我们先从优先队列中取出所有 $endTime < arrival[i]$ 的机台 $idx$,加入「空闲池」,然后再按照「任务分配规则」从空闲池子中取机台,若取不到,则丢弃该任务。
具体的,利用「每个任务有对应的开始时间和持续时间」,我们使用优先队列(堆)维护二元组 $(idx, endTime)$,其中 $idx$ 为机器编号,$endTime$ 为当前机台所处理任务的结束时间(也就是该机台最早能够接受新任务的时刻),对于每个 $arrival[i]$ 而言(新任务),我们先从优先队列中取出所有 $endTime \leqslant arrival[i]$ 的机台 $idx$,加入「空闲池」,然后再按照「任务分配规则」从空闲池子中取机台,若取不到,则丢弃该任务。

由于「任务分配规则」是优先取大于等于 `i % k` 的最小值,若取不到,再取大于等于 $0$ 的最小值。因此我们的「空闲池」最好是支持「二分」的有序集合,容易想到基于「红黑树」的 `TreeSet` 结构。

Expand Down Expand Up @@ -114,6 +114,29 @@ class Solution {
}
}
```

```Python
from sortedcontainers import SortedList

class Solution:
def busiestServers(self, k: int, arrival: List[int], load: List[int]) -> List[int]:
cnts = [0] * k
n, m = len(arrival), 0
busy, free = [], SortedList(range(k))
for i in range(n):
start, end = arrival[i], arrival[i] + load[i]
while busy and busy[0][0] <= start:
free.add(busy[0][1])
heappop(busy)
if (idx := free.bisect_left(i % k)) == len(free) == (idx := free.bisect_left(0)):
continue
u = free[idx]
free.remove(u)
heappush(busy, (end, u))
cnts[u] += 1
m = max(m, cnts[u])
return [i for i in range(k) if cnts[i] == m]
```
* 时间复杂度:令任务数量为 $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})$
* 空间复杂度:$O(k)$

Expand Down