每日刷题第6天 2021.1.1
621.任务调度器
- 难度:中等
- 方法:贪心、排序
题目
- 给你一个用字符数组
tasks表示的CPU需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在1个单位时间内执行完。在任何一个单位时间,CPU可以完成一个任务,或者处于待命状态。 - 然而,两个 相同种类 的任务之间必须有长度为整数
n的冷却时间,因此至少有连续n个单位时间内CPU在执行不同的任务,或者在待命状态。 - 你需要计算完成所有任务所需要的最短时间。
示例
输入:tasks = ["A","A","A","B","B","B"], n = 2
输出:8
解释:A -> B -> (待命) -> A -> B -> (待命) -> A -> B
在本示例中,两个相同类型任务之间必须间隔长度为 n = 2 的冷却时间,而执行一个任务只需要一个单位时间,所以中间出现了(待命)状态。
输入:tasks = ["A","A","A","B","B","B"], n = 0
输出:6
解释:在这种情况下,任何大小为 6 的排列都可以满足要求,因为 n = 0
["A","A","A","B","B","B"]
["A","B","A","B","A","B"]
["B","B","B","A","A","A"]
...
诸如此类
输入:tasks = ["A","A","A","A","A","A","B","C","D","E","F","G"], n = 2
输出:16
解释:一种可能的解决方案是:
A -> B -> C -> A -> D -> E -> A -> F -> G -> A -> (待命) -> (待命) -> A -> (待命) -> (待命) -> A
提示
- `1 <= task.length <= 104`
- `tasks[i]` 是大写英文字母
- `n` 的取值范围为 `[0, 100]`
解法
- 先处理数据,记录每个类型任务的个数,由大到小进行排列
- 再计算空的位置的个数,以及最终的结果(当空位置占完,此时就在ABCABCAB中,ABCDABCD这样添加D,此时绝对不会少于冷却时间,既是最优解)
/**
* @param {character[]} tasks
* @param {number} n
* @return {number}
*/
var leastInterval = function(tasks, n) {
// 1.处理数据
let map = new Map();
for (let i = 0; i < tasks.length; i++) {
if (map.has(tasks[i])) {
map.set(tasks[i], map.get(tasks[i]) + 1);
}else {
map.set(tasks[i], 1);
}
}
// console.log('map', map);
// 对次数进行递减排序
let arr = [...map.values()].sort((a, b) => b - a);
// 2.计算
// 空位置的个数
let space = (arr[0] - 1) * n;
// 最终结果
let ans = space + arr[0];
for (let i = 1; i < arr.length; i++) {
if (arr[i] == arr[0]) {
// space有空
if (space > 0) {
space -= (arr[i] - 1);
ans++;
}else if(space == 0){
// space没空
ans += arr[i];
}
}else {
// 小于
// 有空
if (space > 0) {
if (space >= arr[i]) {
// 大于字母个数
space -= arr[i];
}else {
// 小于字母个数
arr[i] -= space;
space = 0;
ans += arr[i];
}
} else {
// 没空
ans += arr[i];
}
}
}
return ans;
};
附录
map集合可以存储键值对形式的数据map.has()判断集合中是否存在键map.set(key, value)设置键值对map.get(key)获取键对应的值