1. 问题描述:
示例 1:
输入:tasks = ["A","A","A","B","B","B"], n = 2
输出:8
解释:A -> B -> (待命) -> A -> B -> (待命) -> A -> B
在本示例中,两个相同类型任务之间必须间隔长度为 n = 2 的冷却时间,而执行一个任务只需要一个单位时间,所以中间出现了(待命)状态。
示例 2:
输入:tasks = ["A","A","A","B","B","B"], n = 0
输出:6
解释:在这种情况下,任何大小为 6 的排列都可以满足要求,因为 n = 0
["A","A","A","B","B","B"]
["A","B","A","B","A","B"]
["B","B","B","A","A","A"]
...
诸如此类
示例 3:
输入:tasks = ["A","A","A","A","A","A","B","C","D","E","F","G"], n = 2
输出:16
解释:一种可能的解决方案是:
A -> B -> C -> A -> D -> E -> A -> F -> G -> A -> (待命) -> (待命) -> A -> (待命) -> (待命) -> A
提示:
1 <= task.length <= 10 ^ 4
tasks[i] 是大写英文字母
n 的取值范围为 [0, 100]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/task-scheduler
2. 思路分析:
这道题目还是挺有难度的,思路比较难想。在力扣官方的题解中使用的是构造的方法,先统计一下出现次数最多次数的字母,设出现次数最多的字母有k个,分别为A,B,C,D...,最大次数为maxc,当k <= n的时候我们需要将这些每一个相同的字母排成一列,这样这些字母就有maxc行,并且每一行的有n个空位,这些空位首先是安排这些出现次数最多的字母,然后放剩余出现次数小于maxc的字母,对于剩余的字母我们是倒着放的,这样对于相同的字母间隔的数目一定是大于等于n的满足题目的要求,上面放所有字母的时候是属于有空位的情况,所以还存在其余的两种情况分别为k > n和剩余的字母无法放到空位上了,那么我们就需要开另外的列来放这些字母,并且也是倒着放的,新开的这些列相当于是原来的那些字母只是放的位置与原来需要逆着重新排列一下,这样就一定可以满足相同字母的间隔是一定大于等于n的,并且可以发现最终的答案一定是max{(maxc - 1) * (n + 1) + k, len(task)}。
3. 代码如下:
from typing import List
import collections
class Solution:
def leastInterval(self, tasks: List[str], n: int) -> int:
dic = collections.defaultdict(int)
for s in tasks:
dic[s] += 1
maxc, count = 0, 0
for k, v in dic.items():
maxc = max(maxc, v)
for k, v in dic.items():
if v == maxc: count += 1
return max(len(tasks), (maxc - 1) * (n + 1) + count)