池化资源共享 - 华为OD机试真题(JavaScript题解)
华为OD机试题库《C++》限时优惠 9.9
华为OD机试题库《Python》限时优惠 9.9
华为OD机试题库《JavaScript》限时优惠 9.9
针对刷题难,效率慢,我们提供一对一算法辅导, 针对个人情况定制化的提高计划(全称1V1效率更高)。
看不懂有疑问需要答疑辅导欢迎私VX: code5bug
题目描述
有一个局部互联区域内的 n 台设备,每台设备都有一定数量的空闲资源,这些资源可以池化共享。用户会发起两种操作:
- 申请资源:输入
1 x
,表示本次申请需要 x 个资源。系统要返回当前资源池中能满足此申请且剩余资源最少的设备 ID;如果有多台设备满足条件,返回设备 ID 最小的;如果没有任何设备能满足,返回0
并不做任何分配。 - 释放资源:输入
2 y
,表示将第 y 次申请(不一定是成功分配的那一次)释放回原设备。释放时,资源立即归还,且空闲资源自动连续,无需考虑空洞。
给定 n(1 ≤ n ≤ 1000)、操作次数 m(1 ≤ m ≤ 105),以及初始时每台设备的空闲资源数 d₁…dₙ(1 ≤ dᵢ ≤ 1000),以及接下来 m 行操作,输出每次 “申请” 操作的返回值。
输入描述
第一行,输入n和 m
第二行输入n台设备的初始空闲资源数
接下来m行,输出要执行的操作
输出描述
输出每次“申请”操作的返回值。
示例1
输入:
2 2
100 500
1 40
1 450
输出:
1 2
题解
这道题目属于 模拟题,主要考察对操作流程的模拟和数据结构的选择。需要处理两种操作:申请资源和释放资源,并根据特定规则返回结果。
解题思路
- 申请资源操作(
1 x
):
- 遍历所有设备,筛选出当前空闲资源大于
x
的设备。- 对这些设备按照剩余资源升序排序,如果剩余资源相同,则按照设备 ID 升序排序。
- 如果找到满足条件的设备,选择剩余资源最少且 ID 最小的设备,分配资源,并记录分配历史。
- 如果没有满足条件的设备,返回
0
。- 释放资源操作(
2 y
):
- 根据历史记录找到第
y
次申请对应的设备和分配的资源量。- 将资源归还给原设备。
代码描述
- 输入处理:读取设备数量
n
和操作次数m
,以及每台设备的初始空闲资源。- 操作处理:
- 对于申请操作,筛选并排序可用设备,分配资源并记录历史。
- 对于释放操作,根据历史记录归还资源。
- 输出结果:每次申请操作的返回值。
时间复杂度
- 申请操作:每次申请需要遍历所有设备(O(n)),然后排序(O(n log n)),因此最坏情况下为 O(n log n)。
- 释放操作:直接根据历史记录归还资源,O(1)。
- 总时间复杂度:O(m * n log n),其中
m
是操作次数,n
是设备数量。空间复杂度
- 需要存储设备空闲资源数组(O(n))和历史记录(O(m))。
- 总空间复杂度:O(n + m)。
JavaScript
const rl = require('readline').createInterface({input: process.stdin,output: process.stdout,
});var iter = rl[Symbol.asyncIterator]();const readline = async () => (await iter.next()).value;// Author: code5bug
(async () => {let [n, m] = (await readline()).split(' ').map(Number);let free = (await readline()).split(' ').map(Number);// 历史资源的申请情况let history = [];// 每次申请操作的返回值let result = [];for (let i = 0; i < m; i++) {let [type, v] = (await readline()).split(' ').map(Number);// 申请资源if (type === 1) {// 注意, 在 JavaScript 中,箭头函数 => 后面的 { 会被解析为代码块的开始,而不是对象字面量的开始。// 因此,如果你直接写 {value, index} 而没有外层的括号 (),JavaScript 会认为这是一个代码块,而不是返回的对象,从而导致语法错误。let tmp = free.map((value, index) => ({value, index})).filter((item) => item.value > v);// 根据剩余资源和设备ID升序排序tmp.sort((a, b) => a.value - b.value || a.index - b.index);if(tmp.length > 0){idx = tmp[0].index;free[idx] -= v;history.push([idx, v]);result.push(idx + 1);}else{// 没有任何设备能满足history.push([-1, 0]);result.push(0);}// 释放资源}else if(type === 2){let [idx, size] = history[v - 1];if(idx != -1){free[idx] += size;}}}console.log(result.join(' '));rl.close();
})();
希望这个专栏能让您熟练掌握算法, 🎁🎁🎁。
整理题解不易, 如果有帮助到您,请给点个赞 ❤️ 和收藏 ⭐,让更多的人看到。🙏🙏🙏