621.任务调度器
2020-06-12
任务调度器
给定一个用字符数组表示的 CPU 需要执行的任务列表。
其中包含使用大写的 A – Z 字母表示的26 种不同种类的任务。
任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。CPU
在任何一个单位时间内都可以执行一个任务,或者在待命状态。
然而,两个相同种类的任务之间必须有长度为 n 的冷却时间
,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,
或者在待命状态。
你需要计算完成所有任务所需要的最短时间。
题解:
思路1:按出现次数大小排序 贪心算法
冷却时间n + 1为数组arr的长度 arr的第0项是出现最多次的字符 第1项是第二多次的字符 以此类推
每次确定一个字符
就把那个字符的次数-1
/** * @param {character[]} tasks * @param {number} n * @return {number} */ var leastInterval = function (tasks, n) { let hash = {}; // 哈希表 存tasks中有多少种字符 hash.length = 0; // tasks的总长度 for (let i = 0; i < tasks.length; i++) { hash.length++; if (!hash[tasks[i]]) hash[tasks[i]] = 1; // 将每一种字符出现的次数存入hash中 else hash[tasks[i]]++; } let tmp = []; // 存每一种字符与次数的组合数组 例如:[[A, 5], [B, 3], [C, 6]...] Object.keys(hash).forEach(attr => { if (attr !== 'length') tmp.push([attr, hash[attr]]); }) let tmpResult = []; while (hash.length) { // 当hash的length属性的值大于0 进入遍历中 // CD时间为n 说明出现相同任务的间隔为n 也就是每一份数组的长度是n+1 let arr = new Array(n + 1).fill(null); tmp = tmp.sort((a, b) => b[1] - a[1]); // tmp数组按照出现次数的多少排序 多的在最前 // 依次取出出现最多的 第二多的 第三多的。。。放入arr中 // 每次遍历得出一个arr 放入tmpResult中 // 如果第x大的那一项不存在或者那一项的值已经是0 那么退出循环 寻找下一个arr for (let i = 0; i <= n; i++) { if (!tmp[i] || tmp[i][1] === 0) break; arr[i] = tmp[i][0]; tmp[i][1]--; hash.length--; } tmpResult.push(arr); } let result = []; // 将tmpResult合并成一个数组 // 由于arr有可能出现最后一次有多余的null 所以要把尾部的null都删掉 tmpResult.forEach(item => { result = result.concat(item) }); while (result[result.length - 1] === null) result.splice(result.length - 1, 1); return result.length; // result的长度就是次数 };