题目描述:
给定一个用字符数组表示的 CPU 需要执行的任务列表。其中包含使用大写的 A - Z 字母表示的26 种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。CPU 在任何一个单位时间内都可以执行一个任务,或者在待命状态。
然而,两个相同种类的任务之间必须有长度为 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。
你需要计算完成所有任务所需要的最短时间。
示例 1:
输入: tasks = ["A","A","A","B","B","B"], n = 2
输出: 8
执行顺序: A -> B -> (待命) -> A -> B -> (待命) -> A -> B.
注:
任务的总个数为 [1, 10000]。
n 的取值范围为 [0, 100]。
思路:
完成所有任务的最短时间取决于出现次数最多的任务数量。
1、由于两个相同种类的任务之间必须有长度为 n 的冷却时间,因此我们先把出现次数最多的任务A安排上,上面例子中n=2,那么任意两个A任务之间必须要有2个单位的时间:
A -> (单位时间) -> (单位时间) -> A -> (单位时间) -> (单位时间) -> A
2、中间间隔的单位时间可以用来安排别的任务,也可以处于“待命”状态。当然为了是任务在最短时间内完成,我们需要把间隔的单位时间尽可能的安排其他任务,现在我们把B任务也安排上:
A -> B -> (单位时间) -> A -> B -> (单位时间) -> A -> B
3、我们能够看出,前面2个A任务一定会跟着2个单位时间间隔(最后一个A是否还有任务跟随,取决于是否存在与A任务出现次数相同的B任务。)
上面执行顺序的规律是: 有count - 1个A(count为A任务的出现次数),其中每个A需要搭配n个单位时间,再加上最后一个A,所以总时间为 (count - 1) * (n + 1) + 1=(3-1)*(2+1)+1=7;
4、可能会出现多个频率相同的任务,比如 ["A","A","A","B","B","B","C","C"],所以最后会剩下一个A和一个B,因此最后要加上频率相同的不同任务的个数;
5、公式算出的值可能会比数组的长度小,如["A","A","B","B"],n = 0,此时要取数组的长度。
Java解法:
class Solution {
public int leastInterval(char[] tasks, int n) {
int len = tasks.length;
if (len <= 1 || n < 1){
return len;
}
int[] counts = new int[26];
for (int i = 0; i < len; i++)
{
counts[tasks[i]-'A']++;
}
Arrays.sort(counts);
int maxCount = counts[25];
int ans = (maxCount - 1) * (n + 1) + 1;
int j = 24;
while (j >= 0 && counts[j] == maxCount)
{
ans++;
j--;
}
return Math.max(ans, len);
}
}
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers