Java PriorityQueue and TreeSet with explanation - O(nlogk)
Queue to add the running/busy servers after assigning the work load.\nTreeSet to add the available/free servers - treeset maintains ascending order, add the ser
Queue to add the running/busy servers after assigning the work load.\nTreeSet to add the available/free servers - treeset maintains ascending order, add the servers from 0 -> k-1 in the treeset.\nserverHandledReqCount int[] array to keep the count of the requests handled by each server.\n\niterate over the arrival times, if the running servers queue is empty, get the server from the available servers queue.\nwith the formula - available.ceiling(idx % k);\n\nadd the arrivalTime + loadTime = workTime and the server index into the runningServers queue.\n\npeek if the server\'s work time is less than or equal to the next task completion time, if it is poll those servers from the running servers queue and add the index of that server to the availableServerIdxs treeSet\n\nlastly iterate over the serverHandledReqCount[] array and get the max value and add those servers who has the max value into a list and return that list\n\n``` \nclass Solution {\n    public List<Integer> busiestServers(int k, int[] arrival, int[] load) {\n        \n        // use a tree to track available servers\n        TreeSet<Integer> availableServerIdxs = new TreeSet<Integer>();\n        for (int num = 0; num < k; num++) {\n            availableServerIdxs.add(num);\n        }\n        // use a PQ to maintain the availability based on curTime + loadTime and the server index = idx%k\n        Queue<int[]> runningServers = new PriorityQueue<>((a, b)->(a[0] - b[0]));\n        \n        int[] serverHandledReqCount = new int[k];\n        \n        for (int idx = 0; idx < arrival.length; idx++) {\n            int newTaskCompletionTime = arrival[idx];\n            \n          //  peek if the server\'s work time is less than or equal to the next task completion time, if it is poll those servers from the running servers queue and add the index of that server to the availableServerIdxs treeSet\n            while (!runningServers.isEmpty() && runningServers.peek()[0] <= newTaskCompletionTime) {\n                int freedServer = runningServers.poll()[1];\n                availableServerIdxs.add(freedServer);\n            }\n            \n            if (availableServerIdxs.size() == 0) continue; // all busy\n            \n            // to always get the last freed server\n            Integer serverIdx = availableServerIdxs.ceiling(idx % k);\n            \n            if (serverIdx == null) {\n                serverIdx = availableServerIdxs.first();\n            }\n            \n            serverHandledReqCount[serverIdx]++;\n            availableServerIdxs.remove(serverIdx);\n            \n            runningServers.offer(new int[] {newTaskCompletionTime + load[idx], serverIdx});\n        }\n        \n        int max = Arrays.stream(serverHandledReqCount).max().getAsInt();\n        return IntStream.range(0, k).filter(i -> serverHandledReqCount[i] == max).boxed().collect(Collectors.toList());\n        \n        //return findMaxesInCounter(counter);\n    }\n    \n    /*\n    private List<Integer> findMaxesInCounter(int[] counter) {\n        int max = 0;\n        for (int i = 0; i < counter.length; i++) {\n            max = Math.max(max, counter[i]);\n        }\n        List<Integer> result = new ArrayList<>();\n        for (int i = 0; i < counter.length; i++) {\n            if (counter[i] == max) {\n                result.add(i);\n            }\n        }\n        return result;\n    }\n    */\n}
['Heap (Priority Queue)', 'Java']