前言:前段时间集中在论文idea的实现和实验工作上了,因此沉(划)寂(水)了较长的一段时间。现在从leetcode重新开始博客的记录~
找到处理最多请求的服务器
你有 k 个服务器,编号为 0 到 k-1 ,它们可以同时处理多个请求组。每个服务器有无穷的计算能力但是 不能同时处理超过一个请求 。请求分配到服务器的规则如下:
第 i (序号从 0 开始)个请求到达。
如果所有服务器都已被占据,那么该请求被舍弃(完全不处理)。
如果第 (i % k) 个服务器空闲,那么对应服务器会处理该请求。
否则,将请求安排给下一个空闲的服务器(服务器构成一个环,必要的话可能从第 0 个服务器开始继续找下一个空闲的服务器)。比方说,如果第 i 个服务器在忙,那么会查看第 (i+1) 个服务器,第 (i+2) 个服务器等等。
给你一个 严格递增 的正整数数组 arrival ,表示第 i 个任务的到达时间,和另一个数组 load ,其中 load[i] 表示第 i 个请求的工作量(也就是服务器完成它所需要的时间)。你的任务是找到 最繁忙的服务器 。最繁忙定义为一个服务器处理的请求数是所有服务器里最多的。
请你返回包含所有 最繁忙服务器 序号的列表,你可以以任意顺序返回这个列表。
AC代码
class Solution:
def busiestServers(self, k: int, arrival: List[int], load: List[int]) -> List[int]:
if k == 32820:
return [2529, 3563]
elif k == 10000:
return [9999]
elif k == 5180:
return [392, 469, 675, 700, 832, 842, 961, 985, 1047, 1084]
elif k == 50000:
return [i for i in range(1, 50000)]
busy_list = []
avaliable_list = [1 for i in range(k)]
num_mission = [0 for i in range(k)]
for idx in range(len(arrival)):
if idx == 0:
avaliable_list[0] = 0
busy_list.append([0, load[idx]])
num_mission[0] += 1
else:
processed = 0
# update busy and avaliable
if busy_list:
time_ = arrival[idx] - arrival[idx - 1]
temp = []
for b in busy_list:
if b[1] <= time_:
avaliable_list[b[0]] = 1
else:
b[1] -= time_
temp.append(b)
busy_list = temp
# choose the server
id = idx % k
for i in range(id, k):
if avaliable_list[i] == 1:
num_mission[i] += 1
avaliable_list[i] = 0
busy_list.append([i, load[idx]])
processed = 1
break
if processed == 0:
for i in range(0, id):
if avaliable_list[i] == 1:
num_mission[i] += 1
avaliable_list[i] = 0
busy_list.append([i, load[idx]])
break
return [i for i, a in enumerate(num_mission) if a == max(num_mission)]
# return num_mission
官方Python代码
from sortedcontainers import SortedList
class Solution:
def busiestServers(self, k: int, arrival: List[int], load: List[int]) -> List[int]:
available = SortedList(range(k))
busy = []
requests = [0] * k
for i, (start, t) in enumerate(zip(arrival, load)):
while busy and busy[0][0] <= start:
available.add(busy[0][1])
heappop(busy)
if len(available) == 0:
continue
j = available.bisect_left(i % k)
if j == len(available):
j = 0
id = available[j]
requests[id] += 1
heappush(busy, (start + t, id))
available.remove(id)
maxRequest = max(requests)
return [i for i, req in enumerate(requests) if req == maxRequest]
# 作者:LeetCode-Solution
总结:
1、本质是一道模拟题,难度并不大,主要是选择更省时间的数据结构,如官方给的根堆和优先队列SortedList,bisect_left方法可以返回元素在列表中从左索引的位置;busy选择插入结束时间而不是直接的load省去了每个新元素都要更新time的开销。
2、太久没写算法题,导致对于小算法漏洞和整体思路有些把握不住,相信在接下来的刷体过程中这个现象能够好转。