给定一个用字符数组表示的 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 的冷却时间,而执行一个任务只需要一个单位时间,所以中间出现了(待命)状态。
提示:
任务的总个数为 [1, 10000]。
n 的取值范围为 [0, 100]。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/task-scheduler
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
首先思考这样一个问题:有n种任务,每种任务均有m个,而每个任务间隔需要是k,这样需要多少个时间单位?
先说结论:k+1>=n时,为(m-1)*(k+1)+n;当k+1<n时,为任务总个数
如图:(n=3,m=5,k=6) 需要4*7+3=31个时间单位
以下给出证明:
首先,当k+1<n时,可以给出如上图所示类似的排列方式(区别在于此时没有空位)
①由于总存在mn的排列满足要求,因此最小值不会比nm大
②由于该排列所有时间单位均被占满,因此最小值不会比n*m小
由此,此时最小值就是n*m
k+1>=n时,总能给出上图类似的排列方式,因此最小值不会比(m-1)*(k+1)+n大,以下证明不会比(m-1)*(k+1)+n小:
①假设存在长度为(m-1)*(k+1)+n-1的排列
②由于是最小值,易知序列头尾均有任务分配,不妨设尾部任务是任务Mn
③去除最后一个时间单位,去除任务Mn 余下的(m-1)*(k+1)+n-2的序列应该能够容纳n-1种各m个任务
④重复②③直到只剩一种任务,序列长度应该为(m-1)*(k+1)
⑤但是(m-1)*(k+1)+1才能够容纳1种m各任务,与原设矛盾
由此证伪成功,最小值不会比(m-1)*(k+1)+n小
而剩下个数小于m个的任务(转换为原题),只需要插在空白处即可
当然,任务总数大于(m-1)*(k+1)+n时,直接取任务数返回即可
(但是当空位数大于所需插入的任务数时,凭什么就能满足条件往里插?这我还真不会证)
class Solution {
public int leastInterval(char[] tasks, int n) {
int[] flag=new int[26];
//计算所有任务的个数
for(int i=0;i<tasks.length;i++){
flag[tasks[i]-'A']++;
}
int max=-1;
//计算同种任务最多有几个
for(int i=0;i<flag.length;i++){
if(max<flag[i]){
max=flag[i];
}
}
int count=0;
//计算有几种任务到达了最大值
for(int i=0;i<flag.length;i++){
if(flag[i]==max){
count++;
}
}
//计算可能解
int maybe=(max-1)*(n+1)+count;
//返回结果
return Math.max(maybe,tasks.length);
}
}