1606、找到处理最多请求的服务器
你有 k 个服务器,编号为 0 到 k-1 ,它们可以同时处理多个请求组。每个服务器有无穷的计算能力但是 不能同时处理超过一个请求 。请求分配到服务器的规则如下:
第 i (序号从 0 开始)个请求到达。
如果所有服务器都已被占据,那么该请求被舍弃(完全不处理)。
如果第 (i % k) 个服务器空闲,那么对应服务器会处理该请求。
否则,将请求安排给下一个空闲的服务器(服务器构成一个环,必要的话可能从第 0 个服务器开始继续找下一个空闲的服务器)。比方说,如果第 i 个服务器在忙,那么会查看第 (i+1) 个服务器,第 (i+2) 个服务器等等。
给你一个 严格递增 的正整数数组 arrival ,表示第 i 个任务的到达时间,和另一个数组 load ,其中 load[i] 表示第 i 个请求的工作量(也就是服务器完成它所需要的时间)。你的任务是找到 最繁忙的服务器 。最繁忙定义为一个服务器处理的请求数是所有服务器里最多的。
请你返回包含所有 最繁忙服务器 序号的列表,你可以以任意顺序返回这个列表。
示例1:
输入:k = 3, arrival = [1,2,3,4,5], load = [5,2,3,3,3]
输出:[1]
示例2:
输入:k = 3, arrival = [1,2,3,4], load = [1,2,1,2]
输出:[0]
示例3:
输入:k = 3, arrival = [1,2,3], load = [10,12,11]
输出:[0,1,2]
示例4:
输入:k = 3, arrival = [1,2,3,4,8,9,10], load = [5,2,10,3,1,2,2]
输出:[1]
示例5:
输入:k = 1, arrival = [1], load = [1]
输出:[0]
思路:
创建两个存储空间,一个记录服务器空闲的时间,另一个存储每个服务处理的请求数
这段代码的时间复杂度为O(nk),超时了,改进的方案在下方。
class Solution:
def busiestServers(self, k: int, arrival: List[int], load: List[int]) -> List[int]:
servers = [0] * k
requests = [0] * k
# 遍历整个请求,根据请求时间选择合适的服务器进行服务
for i, (start, t) in enumerate(zip(arrival, load)):
for j in range(k):
# 由于需要从i%k之后开始寻找空闲服务器,这里更新j的值
j = (j + i % k) % k
s = servers[j]
# 如果当前服务器的时间为0,即还没有开始工作,或者开始时间大于该服务器工作的时间,也就是服务器已经空闲了
# 让这台服务器进行工作
if s == 0 or start - s >= 0:
requests[j] += 1
servers[j] = start + t
break
# 获取最大的请求数,然后根据最大请求数找出最忙的服务器
maxRequest = max(requests)
return [i for i, req in enumerate(requests) if req == maxRequest]
上面这段代码超时了,那么可以看一下可以改进的地方,首先遍历整个arrival这里,应该调整性不大,那么唯一的调整就是找到可使用的服务器了,这里可以使用优先队列
class Solution:
def busiestServers(self, k: int, arrival: List[int], load: List[int]) -> List[int]:
# 这里存放的是可以工作的服务器
available = list(range(k))
# 工作队列存放的是服务器服务的时间,以及工作的服务器id
works = []
requests = [0] * k
for i, (start, t) in enumerate(zip(arrival, load)):
# 将空闲的服务器假如到可用队列中
while works and works[0][0] <= start:
_, id = heappop(works)
heappush(available, i + (id - i) % k)
# 如果有可用服务器,取出该服务器,假如到工作队列中
if available:
id = heappop(available) % k
requests[id] += 1
heappush(works, (start + t, id))
maxRequest = max(requests)
return [i for i, req in enumerate(requests) if req == maxRequest]