前端算法小白攻略18-leetcode(任务调度器)

485 阅读2分钟

「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战

前言

今天我们来为CPU计算个任务所需最短时间,先跟随题目硬刚一遍,发现在我这外行人这里也还行,我不懂啥贪心算法什么的,就是干。

题目描述

给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。在任何一个单位时间,CPU 可以完成一个任务,或者处于待命状态。

然而,两个相同种类 的任务之间必须有长度为整数 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。

你需要计算完成所有任务所需要的 最短时间 。

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/ta… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

image.png

题目解析

  1. task数组中是我们的任务,如果是相同任务之间,执行的时候需要n个单位的冷却时间
  2. 最好的情况是每个重复元素之间的冷却时间用其他任务来占满,那么我们只要知道重复次数最多(maxExc)的那个任务直接就可以拿到最短时间即 maxExc * (n+1)
  3. 但是我们需要考虑占不满的情况,看上图,我们可以得出最后一行任务,n=2时其实只会执行前一个任务了,后面就不计算冷却时间了,那么,如何得到最后一行任务的个数呢?
    1) 求得相同种类的任务个数等于maxExc的即可,数量计为maxCount
    2) 最短时间即为:(maxExc - 1) * (n + 1) + maxCount
  4. 任务最短时间不可能比任务数短也就是最小时间是task.length,其实就是n=0的时候
  5. 按我们的公式(maxExc - 1) * (n + 1) + maxCount会不会计算出比任务数小的情况呢?这种情况肯定是要排除的
    • 比如说,第二张图中,n=1的时候,A和B是重复次数最多的带入公式: (4-1) * (1+1) + 2 = 8 < task.length = 9

开始解题

/**
 * @param {character[]} tasks
 * @param {number} n
 * @return {number}
 */
var leastInterval = function(tasks, n) {
    const sortObj = _.countBy(tasks); // 1、这里是把任务数分类并计数,比如:['A','A','B'] => { A: 2, B:1 }
    const maxExc = Math.max(...Object.values(sortObj)); // 2、获取所有的任务,取计数的数值最大的即为最大执行数
    let maxCount = 0;
    Object.values(sortObj).forEach(count => {  // 3、找出有几个等于最大执行数的,那就是最后一行任务执行的个数
        if(count === maxExc) {
            maxCount++;
        }
    })
    return Math.max((maxExc-1)*(n+1) + maxCount, tasks.length); // 与任务数相比,用Math.max排除掉不符要求的,最短时间不可能小于task.length;
};