题目:任务调度器
- 给定一个用字符数组表示的 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]。
来源:力扣(LeetCode)第621题
分析:
写在队列的标签里,本质上用的却是贪心算法,不知道为什么,同时还用到了一点hashmap的知识。
思路:
- 要知道最短时间首先要找到出现次数最多的那个值,如果出现次数一样多,选哪个都无所谓。
- 然后看
A-Z
中总共有几个数字出现了,假设最多次数的值是A
,那么第一个A
到第二个A
之间总共还能再放n
个不一样的值。 A -> (单位时间) -> (单位时间) -> A -> (单位时间) -> (单位时间) -> A
- 如果填不满那就为
等待时间
。 - 如果填满了,那就说明不需要
等待时间
就能得到最短时间,所以最短时间就是数组的长度。 - 如果没填满,那么我们可以计算
(出现的次数最多的元素 - 1) * (n + 1) + 出现次数一样多的元素的个数
- 我们依靠出现的次数最多的元素
A
把整个答案划分为a份(a为A
的次数),每一份就是n+1
,由于最后一份不一定是n+1
,所以是(a-1)*(n+1)
,最后在把不相等的最后一份加进去就得到了答案。
代码:
class Solution:
def leastInterval(self, tasks: List[str], n: int) -> int:
count = [0] * 26
for task in tasks:
count[ord(task) - 65] += 1 # 这里是我自己写的简单hash函数,也可以用字典,我这里觉得简单就没用字典。
maxNum = max(count)
maxCount = 0
for c in count:
if c == maxNum:
maxCount += 1
return max((maxNum - 1) * (n + 1) + maxCount, len(tasks))
复杂度分析:
- 时间复杂度:O(n) n为tasks的长度
- 空间复杂度:O(1)
总结:
- 第一次写贪心算法题,标签写错了,本来有想到贪心算法的,可是标签是队列我就一直在想队列,想了半天没有思路。
- 贪心算法得到的有可能是近似解,在使用贪心算法时要想清楚特殊的情况。