LeetCode 1606. 找到处理最多请求的服务器题解

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;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值