题目
(1)给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。在任何一个单位时间,CPU 可以完成一个任务,或者处于待命状态。
(2)然而,两个相同种类的任务之间必须有长度为整数 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。
(3)你需要计算完成所有任务所需要的最短时间 。
(4)示例如下:
输入:tasks = [“A”,“A”,“A”,“B”,“B”,“B”], n = 2
输出:8
解释:A -> B -> (待命) -> A -> B -> (待命) -> A -> B。在本示例中,两个相同类型任务之间必须间隔长度为 n = 2 的冷却时间,而执行一个任务只需要一个单位时间,所以中间出现了(待命)状态。
解决思路
- 先安排出现次数最多的任务,再安排出现次数第二多的任务,再安排出现次数第三多的任务,以此类推。
- 求所需的最短时间的方法:比较图形的面积(即格子总数,如下图所示)和任务总数的大小。
- 当任务的总数量大于格子的数量时,所需的时间为任务总数量。当任务的总数量小于格子的数量时,所需的时间为格子的数量。
- 图形面积计算方法:设任务最多的次数为n次,有m种任务出现了n次,冷却时间为k,则图形的面积为:(n-1) * (k+1) + m,如下图所示:
代码
- C++代码
# include <stdio.h>
# include <vector>
# include <algorithm>
using namespace std;
class Solution {
public:
int leastInterval(vector<char>& tasks, int n) {
// 统计每个大写字母出现的次数,即每种任务出现的次数
int cnt[26] = { 0 };
for (int i = 0; i < tasks.size(); i++) {
cnt[tasks[i] - 'A'] += 1;
}
sort(cnt, cnt + 26); // 对任务次数按照升序进行排序,则出现次数对多的任务在最后一位
// 统计出现次数最多的任务有多少种
int m = 0;
for (int i = 25; i >= 0; i--) {
if (cnt[i] == cnt[25]) { // 排序后,出现次数最多的任务在cnt的最后一个位置
m++;
}
}
return max((cnt[25] - 1) * (n + 1) + m, (int)tasks.size());
}
};
int main() {
Solution *solution = new Solution();
vector<char> task = {'A', 'A', 'A', 'B', 'B', 'B'};
int k = 2;
int ret = solution->leastInterval(task, k);
printf("%d\n", ret);
return 0;
}
- Python代码
# -*- coding: utf-8 -*-
from typing import List
class Solution:
def __init__(self):
pass
def leastInterval(self, tasks: List[str], n: int) -> int:
# 统计每个大写字母出现的次数,即每种任务出现的次数
cnt = [0 for i in range(26)]
for t in tasks:
cnt[ord(t) - ord('A')] += 1
# 对任务次数按照升序进行排序,则出现次数对多的任务在最后一位
cnt.sort() # 等价于 cnt = sorted(cnt)
# 统计出现次数最多的任务有多少种
m: int = 0
for i in range(25, -1, -1):
if cnt[i] == cnt[25]: # 排序后,出现次数最多的任务在cnt的最后一个位置
m += 1
return max(len(tasks), (cnt[25] - 1) * (n + 1) + m)
def main():
solution = Solution()
task = ["A", "A", "A", "B", "B", "B"]
k: int = 2
print(solution.leastInterval(task, k))
if __name__ == "__main__":
main()
说明
- 对应LeetCode第621题。
- 链接:https://leetcode-cn.com/problems/task-scheduler/