前言
题目描述
给定一个用字符数组表示的CPU需要执行的任务列表。其中包含使用大写的A-Z字母表示的26种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以再1个单位时间内执行完,CPU在任何一个单位时间内都可以执行一个任务,或者在待命状态。
然而,两个 相同种类 的任务之间必须有长度为整数 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU
在执行不同的任务,或者在待命状态。 你需要计算完成所有任务所需要的 最短时间 。
题目解析
先看力扣上的一个示例:
也就是说所有任务的最短时间应该是尽量相隔的任务是不重复的,因为如果一旦相隔的任务一样中间就会有待命冷却时间,这样的话就会导致总的时间变长。
解题思路
现在知道了我们要尽量使相隔的任务不重复,那我们就考虑怎么去实现,题解有一种思想是“填桶思想”,我觉得很有意思:
“填桶”的基本思想就是首先划定最小桶区域,(1)以需要执行任务最多的次数作为行(也就是相同字符的次数作为行),以n+1作为列。
(2)然后从次数最多的任务开始依次从上往下,从左到右进行填充。
(3)有可能发生两种情况:填充不满和填充区域不够:
①填充不满:对于填充不满的情况,必须有空闲单位时间在等待,如图:
这种情况下需要的执行时间是:
(n+1)*(max-1)+max count
这里的max count指的是有几个数量都是max的字符,也是最后一个桶的任务数量
②填充区域不够:按照填充顺序继续填充即可。
在这种情况下,需要的执行时间就是:
tasks.length(),这个很容易理解,如果填充的刚刚好,那说明现在相同任务的间隔都满足n,此时就不需要等待时间,如果再继续填充更不用等待了。
思想了解了,接下来的就好办了:
我们只需要记录两个数:
1、纪录最大任务量数N,看一下任务数量并列最多的任务有几个,也就是最后一个桶的任务数X:最后计算num1=(N-1)*(n+1)+X
2、num2=task2.size()
输出其中较大值即可,因为存在空闲时间的话也就是填不满的时候肯定是num1大,不存在空闲时间的话肯定是num2>=num1.
leastInterval代码实现
int leastInterval(vector<char> &tasks,int n){
int len=tasks.size();
if(n==0) return len;
vector<int> vec(26);
int N=0;
for(char c:tasks){
//用来记录不同任务字符的个数
++vec[c-'A'];
N=max(vec[c-'A'],N);
}
ine res=(N-1)*(n+1);
for(int v:vec){
if(v ==N){
res++;
}
}
return max(res,len);
}
完整代码
#include<iostream>
#include<stack>
#include<vector>
using namespace std;
class Solution{
public:
int leastInterval(vector<char> &tasks,int n){
int len=tasks.size();
if(n==0) return len;
vector<int> vec(26);
int N=0;
for(char c:tasks){
//用来记录不同任务字符的个数
++vec[c-'A'];
N=max(vec[c-'A'],N);
}
int res=(N-1)*(n+1);
for(int v:vec){
if(v ==N){
res++;
}
}
return max(res,len);
}
};
int main(){
vector<char> tasks;
int len;
char data;
cin>>len;
for(int i=0;i<len;i++){
cin>>data;
tasks.push_back(data);
}
int n;
cin>>n;
int res=Solution().leastInterval(tasks,n);
//interval:间隔
cout<<res<<endl;
return 0;
}