[路飞]_leetcode刷题_621. 任务调度器

410 阅读4分钟

题目

621. 任务调度器

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

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

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

思路:

这题首先要分析出,有几种场景,模糊分析如下

场景1:任务种类比较少,冷却时间比较长,那么总时间,其实是由数量最多的任务决定的,这种情况不管总任务有多少,都会有消耗一些时间在冷却上。

场景2:任务种类比较多,冷却时间比较短,那么总时间,是由任务总数量决定的

我一开始钻进了一个坑,一直在寻找这两种情况的边界条件,算了很久,发现边界条件很难算,而且最后发现,其实这个边界条件并不重要。

下面我们结合图标来总结归纳一下具体的情况

1.假设只有一种任务A,冷却时间为2,

如下图

A--
A--
A--
Axx

我们把每一行看作一轮任务,那么最后一轮执行完A后就结束了,后续的就不用计算冷却时间了

记A的数量为N,那么我们要进行N轮任务
总时间 == N * (n+1) - n
这里我们换一种思维和写法,方便后面的归纳总结
总时间为 (任务轮数N-1)*(每一轮的任务数n+1) + 最后一轮的任务数
即总时间 == (N-1) * (n+1) + 1
这里总时间为7

A-
A-
A-
Ax

2.有多种任务,但冷却时间较久,n=2

这种情况,其实跟刚才上一种情况是一样的

记A的数量为N 总时间 == (N-1)*(n+1)+1,是10

ABC
AB-
AB-
Axx

3.那假设B再多一个呢,如下图

总时间其实就变成了(N-1)*(n+1)+2,也就是最后+的这个数,并不是固定的,而是数量最多的任务的种类

数量最多的任务的种类为 X

那么总时间 == (N-1)*(n+1)+X

ABC
AB-
AB-
ABx

4.假设C数量增多,则会继续去填满冷却时间, 直到C成为任务最多的任务,那么任务轮数会增多,总体的计算公式仍然是 总时间 == (N-1)*(n+1)+X

CAB
CAB
CAB
CAB
Cxxx

这个时候可以看到,冷却时间已经没有了,最后一轮的-不算冷却时间。

5.假设现在开始任务种类和数量又增多了,但是冷却时间不边,那么我们会按下面这情况执行

这个时候你会发现,刚才的公式行不通了, (N-1)*(n+1)+X = 13

而实际总时间 == 18

这就走进了开始说的场景2

这个时候由于任务种类特别多,把冷却时间占用完之后,就可以排到任意轮次里面去执行

这时候 总时间 == 任务总数量

CABDE
CABDE
CABDx
CABxx
Cxxxx

我们仔细分析一下,不管怎么去排,有一点可以确认的是,所消耗时间一定是大于等于任务数量

总结来说,我们只需要计算这两种情况的时间,取大的那个即可,而并不需要去找到边界做判断

Math.max((N-1)\*(n+1)+X,tasks.length)

具体代码实现如下:

/**
 * @param {character[]} tasks
 * @param {number} n
 * @return {number}
 */
var leastInterval = function(tasks, n) {
    let typeArr = [];
    let countArr = [];
    let time;
    // 把任务按类别归纳
    for(let i=0;i<tasks.length;i++){
        if(typeArr.indexOf(tasks[i]) == -1){
            typeArr.push(tasks[i])
            countArr.push(1)
        }else{
           let index = typeArr.indexOf(tasks[i])
           countArr[index]++
        }
    }
    /  任务种类数量
    let k = typeArr.length;
    let maxTypeNum = Math.max(...countArr);
    let x = 0
    for(let i=0;i<countArr.length;i++){
        if(countArr[i] == maxTypeNum){
            x++;
        }
    }
    let time1 =  (maxTypeNum-1)*(n+1)+x;
    let time2 = tasks.length;
    time = Math.max(time1,time2);
    return time;
};