LeetCode 621. 任务调度器 (Java)

题目:

给定一个用字符数组表示的 CPU 需要执行的任务列表。其中包含使用大写的 A - Z 字母表示的26 种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。CPU 在任何一个单位时间内都可以执行一个任务,或者在待命状态。

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

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

 

示例 :

输入:tasks = ["A","A","A","B","B","B"], n = 2
输出:8
解释:A -> B -> (待命) -> A -> B -> (待命) -> A -> B.
在本示例中,两个相同类型任务之间必须间隔长度为 n = 2 的冷却时间,而执行一个任务只需要一个单位时间,所以中间出现了(待命)状态。
 

分析:

给定一系列任务以及间隔数,求出完成任务的最短时间。

统计出同一种任务个数的最大值,实际上我们需要优先将该任务进行分配,观察示例不难发现,任务数最多的A有三个,那么可以建立一个任务表来添加任务。

A    
A    
A    

每两个相同任务间需要隔两个时间,那么每一行只要填入不同的任务即可。

A B null
A B null
A B  

按照这个例子我们可以得出一个公式,那就是q是拥有相同最大任务数的任务种类个数,n表示间隔时间,max是最大任务数,则最短时间为(max-1)*(n+1) + q,示例就是(3-1)*(2+1)+2=8。

如果示例改为AAABBBC的话,最短时间依旧是8

A B C
A B null
A B  

实际上,只要总任务数小于依据公式计算出的结果,答案都是计算出的结果,因为任务都可以分配到表中,但是当任务总数大于计算的答案时,结果就等于任务数了。

因为无论怎么样,都可以不出现待命状态,而完美的分配任务。

以AAABBBCCDD为例,以之前的想法我们建立安排表,将任务加入

A B C
A B C
A B  

此时还有两个D,则可以再增加一列,不会影响已经安排的任务,即任务之间需要间隔的冷却时间是不会被破坏的。

A B C D
A B C D
A B    

答案就是任务数。

程序:

class Solution {
    public int leastInterval(char[] tasks, int n) {
        int[] arr = new int[26];
        for(char ch:tasks){
            arr[ch-'A']++;
        }
        int maxNum = Arrays.stream(arr).max().getAsInt();
        int q = 0;
        for(int a:arr){
            if(a == maxNum)
                q++;
        }
        int res = (maxNum - 1) * (n+1) + q;
        return res > tasks.length ? res : tasks.length;
    }
}

 

posted @ 2020-11-20 15:47  silentteller  阅读(192)  评论(0编辑  收藏  举报