[Python] O(NlogK) SortedList and Heap
Approach 1. Simulate (TLE)\n\nWe do exactly what we are told in the problem statement.\npython \nclass Solution:\n    def busiestServers(self, k: int, arrival: 
Approach 1. Simulate (TLE)\n\nWe do exactly what we are told in the problem statement.\n```python \nclass Solution:\n    def busiestServers(self, k: int, arrival: List[int], load: List[int]) -> List[int]:\n        endtimes = [0] * k\n        count    = [0] * k\n        \n        for aidx, (a, l) in enumerate(zip(arrival, load)):\n            serveridx = aidx % k\n            if endtimes[serveridx]<=a:\n                count[serveridx]+=1\n                endtimes[serveridx] = a+l\n            else:\n                nextserveridx = (serveridx + 1) % k\n                while nextserveridx != serveridx:\n                    if endtimes[nextserveridx] <= a:\n                        count[nextserveridx]+=1\n                        endtimes[nextserveridx] = a + l\n                        break\n                    nextserveridx = (nextserveridx + 1) % k\n        \n        max_ = max(count)\n        ans = []\n        for i in range(k):\n            if count[i]==max_:\n                ans.append(i)\n        return ans\n```\nN=number of requests\nK=number of servers\nTime: O(NK)\nSpace: O(K)\n\nApproach 2. Use SortedList and Heap\n\nWe need to find a better way to find the next available server. Since we need to find the next available server in a circular way, we can use a SortedList to give us O(logK) time for finding the next available server. And we also need to remember the servers that are curently used. We can use a heap to keeptrack of the earliest ending request and pop it when a new request starts later.\n\n```python\nfrom sortedcontainers import SortedList\nclass Solution:\n    def busiestServers(self, k: int, arrival: List[int], load: List[int]) -> List[int]:\n        count = [0] * k # keep track of how many requests handled each server\n        \n        available_servers = SortedList(range(k)) # a sorted list containing indices of available servers\n        heap_endtimes = [] # use a heap data structure that contains tuples (end_time, server_idx)\n        \n        for aidx, (a, l) in enumerate(zip(arrival, load)):\n            while h and h[0][0] <= a: # when a new request start time is greater that the endtime of any request\n                _, free_server_idx = heapq.heappop(heap_endtimes) # free the server  from the hea[\n                available_servers.add(free_server_idx) # and add it to the available servers list\n\n\t\t\tif len(available_servers)==0: \n                continue\n                \n            serveridx = aidx % k # which server should handle this request according to the presented rule?\n            i = available_servers.bisect_left(serveridx) % len(available_servers) # i will point either to the serveridx if it exists in the sorted list, or it will point to the next one\n            actual_server = available_servers.pop(i) # remove the server from the available list\n            count[actual_server]+=1 # increment the number of times the server had been used\n            heapq.heappush(heap_endtimes, (a+l, actual_server)) # make the server end at a+l\n            \n        max_ = max(count)\n        ans = []\n        for i in range(k):\n            if count[i]==max_:\n                ans.append(i)\n        return ans\n```\nTime: O(NlogK)\nSpace: O(K)
[]