1606. 找到处理最多请求的服务器

exiaohu 于 2022-03-30 发布

题目链接:1606. 找到处理最多请求的服务器

使用一个有序列表维护空闲服务器的集合,使用一个优先队列维护繁忙服务器的集合。

当第 $i$ 个新请求到来时:

  1. 先将繁忙服务器中已经变为空闲的服务器找出来,并加入到空闲服务器列表中;
  2. 如果无服务器空闲,丢弃这个请求,进行下一步;
  3. 按以下顺序寻找一个合适的服务器处理请求:
    • 如果编号为 $i\%k$ 的服务器空闲,使用该服务器处理请求,在有序列表中寻找特定值,时间复杂度为 $O(log(n))$;
    • 在空闲服务器列表中寻找最小的,编号大于 $i\%k$ 的服务器,时间复杂度也是 $O(log(n))$;
    • 使用空闲服务器中编号最小的处理请求。
import heapq
from collections import defaultdict
from typing import List

from sortedcontainers import SortedList


class Solution:
    def busiestServers(self, k: int, arrival: List[int], load: List[int]) -> List[int]:
        counter, idles, busys = defaultdict(int), SortedList(range(k)), []

        def dispatch(n, l):
            idles.remove(n)
            heapq.heappush(busys, (l, n))
            counter[n] += 1

        for i, (a, l) in enumerate(zip(arrival, load)):
            while busys:
                d, n = heapq.heappop(busys)
                if d <= a:
                    idles.add(n)
                else:
                    heapq.heappush(busys, (d, n))
                    break

            if not idles:
                continue

            if i % k in idles:
                dispatch(i % k, a + l)
            else:
                idx = idles.bisect(i % k)
                if idx < len(idles):
                    dispatch(idles[idx], a + l)
                else:
                    dispatch(idles[0], a + l)

        busiests, busy = [], -1
        for key, val in counter.items():
            if val > busy:
                busiests = [key]
                busy = val
            elif val == busy:
                busiests.append(key)
        return busiests