621. 任务调度器(笔试题)

419 阅读2分钟

每日刷题第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)获取键对应的值