【Leetcode】每日一题:找到处理最多请求的服务器

前言:前段时间集中在论文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、太久没写算法题,导致对于小算法漏洞和整体思路有些把握不住,相信在接下来的刷体过程中这个现象能够好转。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值