题目:
给定一个用字符数组表示的 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; } }