LeetCode 1882 使用服务器处理任务

81 篇文章 1 订阅
12 篇文章 0 订阅
本文介绍了一种通过双优先队列实现的高效算法,用于在给定服务器权重和任务处理时间的情况下,动态分配任务以最小化处理时间。通过模拟服务器空闲与任务排队的过程,构建了长度为m的任务分配数组。实例演示了如何使用该方法解决实际问题并优化资源利用。
摘要由CSDN通过智能技术生成

题目链接

给你两个 下标从 0 开始 的整数数组 servers 和 tasks ,长度分别为 n​​​​​​ 和 m​​​​​​ 。servers[i] 是第 i​​​​​​​​​​ 台服务器的 权重 ,而 tasks[j] 是处理第 j​​​​​​ 项任务 所需要的时间(单位:秒)。

你正在运行一个仿真系统,在处理完所有任务后,该系统将会关闭。每台服务器只能同时处理一项任务。第 0 项任务在第 0 秒可以开始处理,相应地,第 j 项任务在第 j 秒可以开始处理。处理第 j 项任务时,你需要为它分配一台 权重最小 的空闲服务器。如果存在多台相同权重的空闲服务器,请选择 下标最小 的服务器。如果一台空闲服务器在第 t 秒分配到第 j 项任务,那么在 t + tasks[j] 时它将恢复空闲状态。

如果没有空闲服务器,则必须等待,直到出现一台空闲服务器,并 尽可能早 地处理剩余任务。 如果有多项任务等待分配,则按照 下标递增 的顺序完成分配。

如果同一时刻存在多台空闲服务器,可以同时将多项任务分别分配给它们。

构建长度为 m 的答案数组 ans ,其中 ans[j] 是第 j 项任务分配的服务器的下标。

返回答案数组 ans​​​​ 。

示例 1:

输入:servers = [3,3,2], tasks = [1,2,3,2,1,2]
输出:[2,2,0,2,1,2]
解释:事件按时间顺序如下:
- 0 秒时,第 0 项任务加入到任务队列,使用第 2 台服务器处理到 1 秒。
- 1 秒时,第 2 台服务器空闲,第 1 项任务加入到任务队列,使用第 2 台服务器处理到 3 秒。
- 2 秒时,第 2 项任务加入到任务队列,使用第 0 台服务器处理到 5 秒。
- 3 秒时,第 2 台服务器空闲,第 3 项任务加入到任务队列,使用第 2 台服务器处理到 5 秒。
- 4 秒时,第 4 项任务加入到任务队列,使用第 1 台服务器处理到 5 秒。
- 5 秒时,所有服务器都空闲,第 5 项任务加入到任务队列,使用第 2 台服务器处理到 7 秒。

示例 2:

输入:servers = [5,1,4,3,2], tasks = [2,1,2,4,5,2,1]
输出:[1,4,1,4,1,3,2]
解释:事件按时间顺序如下:
- 0 秒时,第 0 项任务加入到任务队列,使用第 1 台服务器处理到 2 秒。
- 1 秒时,第 1 项任务加入到任务队列,使用第 4 台服务器处理到 2 秒。
- 2 秒时,第 1 台和第 4 台服务器空闲,第 2 项任务加入到任务队列,使用第 1 台服务器处理到 4 秒。
- 3 秒时,第 3 项任务加入到任务队列,使用第 4 台服务器处理到 7 秒。
- 4 秒时,第 1 台服务器空闲,第 4 项任务加入到任务队列,使用第 1 台服务器处理到 9 秒。
- 5 秒时,第 5 项任务加入到任务队列,使用第 3 台服务器处理到 7 秒。
- 6 秒时,第 6 项任务加入到任务队列,使用第 2 台服务器处理到 7 秒。

数据结构+模拟~
开两个优先队列即可,一个是空闲队列,一个是任务队列(PS:都是小根堆)~
空闲队列 f r e e free free 存一个 p a i r ( x , y ) pair(x,y) pair(x,y) x x x 为服务器权重, y y y 为服务器编号~
任务队列 t a s k task task 存一个 t u p l e ( x , y , z ) tuple(x,y,z) tuple(x,y,z) x x x 为任务完成后的时间, y y y 为服务器权重, z z z 为服务器编号~
此时我们维护一个当前时间 t t t,建立一个服务器编号到权重的映射数组 f u c k fuck fuck,下面模拟一下过程:

  1. 假设当前遍历到任务 i i i
  2. 首先是释放任务队列中的服务器,令 [ a , b , c ] = w o r k . t o p ( ) [a,b,c]=work.top() [a,b,c]=work.top(),若 t ≥ a t\geq a ta 则证明该服务器已完成任务,将队头弹出,并将 p a i r ( f u c k [ c ] , [ c ] ) pair(fuck[c],[c]) pair(fuck[c],[c]) 存入空闲队列
  3. 然后判断空闲队列是否为空,不为空就取空闲队列的队头中的服务器,令 [ a , b ] = f r e e . t o p ( ) [a,b]=free.top() [a,b]=free.top(),弹出队头并将 t u p l e ( t a s k [ i ] + t , f u c k [ b ] , b ) tuple(task[i]+t,fuck[b],b) tuple(task[i]+t,fuck[b],b) 存入任务队列
  4. 若空闲队列为空,则取任务队列中的队头中的服务器,令 [ a , b , c ] = w o r k . t o p ( ) [a,b,c]=work.top() [a,b,c]=work.top(),弹出队头并将 t u p l e ( t a s k [ i ] + a , f u c k [ c ] , c ) tuple(task[i]+a,fuck[c],c) tuple(task[i]+a,fuck[c],c) 存入任务队列
  5. 实时更新时间 t t t

AC代码如下:

typedef tuple<int, int, int> T;
typedef pair<int, int> P;

class Solution {
public:
    int fuck[200005];
public:
    vector<int> assignTasks(vector<int> &servers, vector<int> &tasks) {
        priority_queue<P, vector<P>, greater<>> free;
        priority_queue<T, vector<T>, greater<>> work;
        vector<int> ans;
        vector<T> v;
        int t;
        for (int i = 0; i < servers.size(); i++) free.push(P(servers[i], i)), fuck[i] = servers[i];
        for (int i = 0; i < tasks.size(); i++) {
            t = max(t, i);
            while (!work.empty()) {
                auto[a, b, c]=work.top();
                if (t >= a) {
                    free.push(P(fuck[c], c));
                    work.pop();
                } else break;
            }
            if (!free.empty()) {
                auto[a, b]=free.top();
                free.pop();
                ans.push_back(b);
                work.push(T(tasks[i] + t, fuck[b], b));
            } else {
                auto[a, b, c]=work.top();
                ans.push_back(c);
                work.pop();
                work.push(T(tasks[i] + a, fuck[c], c));
                t = a;
            }
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旺 崽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值