思路:根据每个任务有对应的开始时间和持续时间,用优先队列busy维护二元组(结束时间,服务器编号),按结束时间从早到晚排列。
根据任务分配规则,用红黑树free维护空闲服务器编号,根据编号从小到大排列。
#include<iostream>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
using namespace std;
class Solution {
public:
vector<int> busiestServers(int k, vector<int>& arrival, vector<int>& load) {
int Max=0;
vector<int>cnts(k,0);//统计每个服务器处理的请求数
set<int>free;//空闲服务器,按编号从小到大排列,用红黑树存储
//set:set 中不允许重复的元素,每个元素在 set 中最多只能出现一次。
//multiset:multiset 允许存储重复的元素,同一个值可以在 multiset 中出现多次。
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<>> busy;
//根据 pair 对象的第一个元素进行排序,并根据其值的大小获取最小的元素
for(int i=0;i<=k-1;i++){
free.insert(i);
}
for(int i=0;i<arrival.size();i++){
int start=arrival[i],end=arrival[i]+load[i];
//根据时间调整free和busy
while(!busy.empty()&&busy.top().first<=start){
free.insert(busy.top().second);
busy.pop();
}
if(free.empty()==true){
continue;
}
//找空闲服务器
auto it=free.lower_bound(i%k);
//第(i%k)个服务器非空闲,将请求安排给下一个空闲的服务器,所以用lower_bound,不能用find
int u;
if(it!=free.end()){
u=*it;
cnts[u]++;
Max=max(Max,cnts[u]);
busy.emplace(end,u);
free.erase(it);
}
else{
auto t=free.begin();
u=*t;
cnts[u]++;
Max=max(Max,cnts[u]);
busy.emplace(end,u);
free.erase(t);
}
/*
if(it==free.end()){
it=free.begin();
}
cnts[*it]++;
busy.emplace(end,*it);
free.erase(it);
*/
}
vector<int>res;
//int Max=*max_element(cnts.begin(),cnts.end());
for(int i=0;i<k;i++){
if(cnts[i]==Max){
res.push_back(i);
}
}
return res;
}
};