1606. 找到处理最多请求的服务器题解
题目来源:1606. 找到处理最多请求的服务器
2022.03.30 每日一题
LeetCode 题解持续更新中Github仓库地址 CSDN博客地址
我们可以来模拟这个过程,创建两个一个 集合 一个优先队列,分别用来统计当前可用的服务器以及当前正在工作的服务器,
然后在处理 arrival 的时候,首先判断在当前正在工作的服务器中有没有工作完成的 ,如果有,就将其移入可用服务器队列,如果没有就进行下一步,寻找可以使用的服务器
关于寻找服务器,我们首先第一步是寻找大于等于 i%k 的服务器,如果不存在就使用 当前第一个(set)
寻找到对应的服务器以后将对应的服务器索引放入正在工作的服务器之中,更新每个使用的服务器的数目,得到最大值
class Solution {
public:
vector<int> busiestServers(int k, vector<int> &arrival,vector<int> &load) {
// 创建 available 的集合,用来统计当前可以使用的服务器
set<int> available;
// 创建结果数组
vector<int>res;
// 创建队列用来统计当前在工作的服务器
// 为什么要使用 PriorityQueue 呢:因为 PriorityQueue 优先队列的作用是能保证每次取出的元素都是队列中权值最小的(Java的优先队列每次取最小元素
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> busy;
// 创建 cnt 数组用于统计每个服务器处理 request 的次数
int cnt[k];
// 当开始的时候所有的服务器都是可以使用的,将所有的服务器放入 available 之中
for (int i = 0; i < k; i++) available.insert(i);
for (int i = 0; i < arrival.size(); i++) {
// 判断 当前 busy 是否为空,不为空就取出第一个,将其结束时间与 arrival[i] 的到达时间进行比较
// 使用循环,是为了防止有多个满足条件的情况存在,这时候就要都放出来
while (!busy.empty() && busy.top().first <= arrival[i]) {
// 如果满足在 arrival[i] 到达之前空闲,就将其加入 available 之中
available.insert(busy.top().second);
}
// 如果当前可用列表为空,说明没有服务器可以处理当前的 request 应当进行舍弃
if (available.empty()) continue;
// 到这里了,说明我们可以进行寻找可以使用的服务器了
// 首先寻找 >= i%k 的服务器,如果不存在,就 使用最小的节点
auto temp = available.lower_bound(i % k);
if (temp == available.end()) temp = available.begin();
// 对应的服务器统计数组也要加一
cnt[*temp]++;
// 并将 此次使用的服务器,连同其结束时间一起放入 busy 数组
busy.emplace(arrival[i] + load[i], *temp);
available.erase(temp);
}
// 找到 cnt 数组中的最大值
int m = 0;
// 将数组中与最大值相同的值都放入结果数组之中
for (int i = 0; i < k; i++)
if (cnt[i] == m) {
res.push_back(i);
continue;
} else if (cnt[i] > m) {
m = cnt[i];
res.clear();
res.push_back(i);
}
return res;
}
};
class Solution {
public List<Integer> busiestServers(int k, int[] arrival, int[] load) {
// 创建 available 的集合,用来统计当前可以使用的服务器
TreeSet<Integer> available = new TreeSet<>();
// 创建结果数组
ArrayList<Integer> res = new ArrayList<>();
// 创建队列用来统计当前在工作的服务器
// 为什么要使用 PriorityQueue 呢:因为 PriorityQueue 优先队列的作用是能保证每次取出的元素都是队列中权值最小的(Java的优先队列每次取最小元素
PriorityQueue<int[]> busy = new PriorityQueue<>((b1, b2) -> b1[0] - b2[0]);
// 创建 cnt 数组用于统计每个服务器处理 request 的次数
int[] cnt = new int[k];
// 当开始的时候所有的服务器都是可以使用的,将所有的服务器放入 available 之中
for (int i = 0; i < k; i++) available.add(i);
for (int i = 0; i < arrival.length; i++) {
// 判断 当前 busy 是否为空,不为空就取出第一个,将其结束时间与 arrival[i] 的到达时间进行比较
// 使用循环,是为了防止有多个满足条件的情况存在,这时候就要都放出来
while (!busy.isEmpty() && busy.peek()[0] <= arrival[i]) {
// 如果满足在 arrival[i] 到达之前空闲,就将其加入 available 之中
available.add(busy.poll()[1]);
}
// 如果当前可用列表为空,说明没有服务器可以处理当前的 request 应当进行舍弃
if (available.isEmpty()) continue;
// 到这里了,说明我们可以进行寻找可以使用的服务器了
// 首先寻找 >= i%k 的服务器,如果不存在,就 使用最小的节点
Integer temp = available.ceiling(i % k);
if (temp == null) temp = available.first();
// 对应的服务器统计数组也要加一
cnt[temp]++;
// 并将 此次使用的服务器,连同其结束时间一起放入 busy 数组
busy.add(new int[]{arrival[i] + load[i], temp});
available.remove(temp);
}
// 找到 cnt 数组中的最大值
int m = 0;
// 将数组中与最大值相同的值都放入结果数组之中
for (int i = 0; i < k; i++)
if (cnt[i] == m) {
res.add(i);
continue;
} else if (cnt[i] > m) {
m = cnt[i];
res.clear();
res.add(i);
}
return res;
}
}