1. 程式人生 > 實用技巧 >a_lc_找到處理最多請求的伺服器(treemap+treeset)

a_lc_找到處理最多請求的伺服器(treemap+treeset)

伺服器不能同時處理超過一個請求,1~k這些伺服器順序接受請求;
若k個伺服器都在處理請求,那麼新來的請求會被扔掉,否則,誰空閒就輪到誰接;
問接受請求最多的伺服器時哪個

思路

  • set維護當前空閒伺服器列表free(按id升序排列)
  • map/pq(這裡用treemap)維護存每個時間點對應的所有伺服器列表,當請求arrival[i]到來時,我就去map中找執行時間在arrival[i]及之前結束的伺服器列表,將他們全部add到set中,歸為空閒伺服器
class Solution {
    public List<Integer> busiestServers(int k, int[] arrival, int[] load) {
        int n=load.length, max=0, cnt[] = new int[k];
        TreeMap<Integer, List<Integer>> tmap = new TreeMap<Integer, List<Integer>>();
        TreeSet<Integer> free = new TreeSet<>();
        for (int i=0; i<k; i++) free.add(i);

        for (int i=0; i<n; i++) {
            var map = tmap.headMap(arrival[i], true); //找到小於等於當前請求到達時間就空閒的所有伺服器
            var it = map.entrySet().iterator();
            while (it.hasNext()) {
                var data = it.next();
                free.addAll(data.getValue());
                it.remove();
            }
            if (free.isEmpty()) continue;
            Integer id = i%k, candidate = free.ceiling(id); //找到≥id的最小伺服器編號
            if (candidate==null) candidate = free.first(); //如果free不空但找不到,證明當前id是最大的編號
            tmap.computeIfAbsent(arrival[i]+load[i], v->new LinkedList<>()).add(candidate);
            free.remove(candidate);
            cnt[candidate]++;
            if (cnt[candidate]>max) max = cnt[candidate];
        }
        LinkedList<Integer> ans = new LinkedList<Integer>();
        for (int i=0; i<k; i++) if (cnt[i]==max)
            ans.add(i);
        return ans;
    }
}