题目
给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。在任何一个单位时间,CPU 可以完成一个任务,或者处于待命状态。
然而,两个 相同种类 的任务之间必须有长度为整数 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。
你需要计算完成所有任务所需要的 最短时间 。
例如:
输入:tasks = [“A”,“A”,“A”,“B”,“B”,“B”], n = 2
输出:8
解释:A -> B -> (待命) -> A -> B -> (待命) -> A -> B
在本示例中,两个相同类型任务之间必须间隔长度为 n = 2 的冷却时间,而执行一个任务只需要一个单位时间,所以中间出现了(待命)状态。
https://leetcode-cn.com/problems/task-scheduler/
基本思路
(1)构建一个 优先队列,大顶堆,用于存剩余任务的次数。例如 [ 8,5,5,4,3],此处不区分任务种类,因为即使两个任务数量一样,相对次序不影响结果。可以把希望的次序作为要使用的次序。
(2)以任务间隔 作为一个周期,按任务次数的多少依次取出数量最大的任务,
如果间隔够大,所有任务取一遍也不能填满,那么就用空白代替,取出任务的数量都减一,数量不为0的,再添加到 队列中。
如果间隔较小,任务取一部分就填满间隔,那么取出任务的数量都减一,数量不为0的,再添加到 队列中。
代码
class Solution {
public:
int leastInterval(vector<char>& tasks, int n) {
int ans = 0;
priority_queue<int> p_que; //建立一个自动排序的大顶堆
unordered_map<char,int> num_map;
for(const auto &r:tasks){ //统计每个任务的个数
++num_map[r];
}
for(const auto &r:num_map){ //压入大顶堆
//cout<<r.second<<endl;
p_que.push(r.second);
}
while(!p_que.empty()){ //任务未完成的时候,继续执行任务
vector<int> temp; //用于存下,已经执行,但是还剩余执行次数的任务
for(int i=0;i<=n;++i){ //以间隔次数作为一个周期
++ans; //记下花费的单位时间
if(!p_que.empty()){ //在一个间隔内,队列中还有其他任务没有被做过
if(p_que.top() - 1 != 0){ //做队列中剩余次数最多的任务
temp.push_back(p_que.top() - 1); //如果还有剩余,暂时先存下
}
p_que.pop(); //弹出做过的任务
}
if(p_que.empty() && temp.size()==0)
break;//如果队列 和 暂存temp 都为空,说明任务已经完成
}
for(const auto &r:temp){ //一个周期之后,将temp 中的任务再添加回来。
p_que.push(r);
}
}
return ans;
}
};
大顶堆
https://blog.csdn.net/xiaoquantouer/article/details/52015928?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control
参考
https://blog.csdn.net/stone_fall/article/details/89010656?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control
参考
学习例子:
class Solution {
public:
int leastInterval(vector<char>& tasks, int n) {
auto cmp = [&](vector<int> &letter1, vector<int> &letter2){
return letter1[1] < letter2[1];
};
priority_queue<vector<int>, vector<vector<int>>,decltype(cmp)> p_que(cmp);
unordered_map<int,int> num_map;
for(const auto &r:tasks){
++num_map[r - 'A'];
}
for(const auto &r:num_map){
vector<int> temp;
temp.push_back(r.first);
temp.push_back(r.second);
p_que.push(temp);
}
while( !p_que.empty()){
cout<<p_que.top()[1]<<endl;
p_que.pop();
}
return 0;
}
};