一、题目说明
题目621. Task Scheduler,给定一列字符列表(A~Z)表示CPU执行的任务,可以任意执行,每个任务在1单位时间执行完成,CPU在一个单位时间内可以执行一个任务,或者处于IDEL状态。两个相同类型任务必须有n单位冷却时间。计算任务执行所需的最少时间。
二、我的解答
看到这个题目,我能想到的就是,统计每个任务的次数,然后从次数从高到低排序,放入数组中。向将A插入数组
先把A插入数组中, 变成 A $ $ A $ $ A $ $ A
,再将B插入数组中A B $ A B $ A B $ AB
,返回数组的长度即可。下面的解答是错误的:
class Solution{
public:
//该解答错误在于每次取出数量最高的任务,全部安排好。继续取数量最高的任务不对
//正确的解答是每次取出n+1个任务
int leastInterval(vector<char>& tasks,int n){
if(tasks.size()<1) return 0;
if(tasks.size()<2) return 1;
//if(n==1) return tasks.size();
res.clear();
ump.clear();
//统计每个任务出现的次数
for(int i=0;i<tasks.size();i++){
ump[tasks[i]]++;
}
for(unordered_map<char,int>::iterator iter=ump.begin();iter!=ump.end();iter++){
cout<<iter->first<<"="<<iter->second<<"->";
}
cout<<"
";
bool first = true;
while(ump.size()>0){
char curr = findMaxNum(ump);
int num = ump[curr];
ump.erase(curr);
if(first){
//第一个任务
while(num>1){
res.push_back(curr);
for(int j=0;j<n;j++){
res.push_back('$');
}
num--;
}
res.push_back(curr);
first = false;
}else{
//其他任务 填空
int tmp = 1;
while(num>0 && tmp<res.size()){
if(res[tmp]=='$'){
res[tmp] = curr;
tmp = tmp + n + 1;
num--;
}else{
tmp++;
}
}
if(num<1){
continue;
}else{
if(tmp>res.size()){
while(tmp>res.size()){
res.push_back('$');
}
}
res.push_back(curr);
num--;
}
while(num>0){
for(int j=0;j<n;j++){
res.push_back('$');
}
res.push_back(curr);
num--;
}
}
}
for(int t=0;t<res.size();t++){
cout<<res[t]<<"->";
}
cout<<"
";
return res.size();
}
private:
vector<char> res;
unordered_map<char,int> ump;
char findMaxNum(unordered_map<char,int>& ump){
int maxNum=0;
char maxChar;
for(unordered_map<char,int>::iterator iter=ump.begin();iter!=ump.end();iter++){
if(iter->second > maxNum){
maxChar = iter->first;
maxNum = iter->second;
}
}
return maxChar;
}
};
正确的应该是:
class Solution{
public:
//采用优先级队列,次数最高的在前面
int leastInterval(vector<char>& tasks,int n){
int res = 0;
int cycle = n+1;
unordered_map<char,int> ump;
priority_queue<int> q;
for(char c: tasks){
ump[c]++;
}
for(auto a:ump){
q.push(a.second);
}
while(! q.empty()){
int cnt = 0;
vector<int> t;
//每次取出n+1个元素
for(int i=0;i<cycle;i++){
if(! q.empty()){
t.push_back(q.top());
q.pop();
++cnt;
}
}
for(int d: t){
if(--d >0){
q.push(d);
}
}
res += q.empty() ? cnt : cycle;
}
return res;
}
};
性能如下:
Runtime: 148 ms, faster than 25.51% of C++ online submissions for Task Scheduler.
Memory Usage: 19.3 MB, less than 29.79% of C++ online submissions for Task Scheduler.
三、优化措施
用公式解答最方便:网上很多解答,我就不注解了。
class Solution{
public:
int leastInterval(vector<char>& tasks,int n){
unordered_map<char,int> ump;
int count = 0,same=0,res = 0;
for(char c: tasks){
ump[c]++;
count = max(count,ump[c]);
}
for(auto c: ump){
if(c.second == count){
++same;
}
}
res = (count-1)*(n+1) + same;
return max(res,(int)tasks.size());
}
};
性能如下:
Runtime: 68 ms, faster than 62.56% of C++ online submissions for Task Scheduler.
Memory Usage: 9.8 MB, less than 78.72% of C++ online submissions for Task Scheduler.