题目描述如下:

思路:
要想完成任务的时间最短,那么必须优先处理出现次数最多的任务(如果将次数多的任务留到最后,必然在每次任务之间留出大量的等待时间),因此我们可以以n+1个任务为一轮(保证同一种任务不出现在同一轮),每一轮按出现次数顺序从大到小执行,每完成一轮就重新排序依次,直到所有任务完成;
例如:AAABBBBC n=2
首先统计任务次数,然后排序得到 4 3 1
初始time=0
每一轮任务个数为3
第一轮 :从次数为4的任务开始,执行一次++time ,然后3执行依次,++time, 然后1执行依次,++time;
完成后再排序有 3 2
第二轮:次数为3的任务执行一次,++time, 次数为2的任务执行一次,++time,本轮找不到剩下可执行的任务,此时需等待一个单位时间,++time
完成后再排序有 2 1
第三轮:*依次类推。。。++time ,++time,++time(等待)
完成后再排序有 1
第四轮:++time (所有任务完成,不需要另外等待两个单位时间)
最后time=10
以上思路转换为代码如下:
方法一:
class Solution {
public:
int leastInterval(vector<char>& tasks, int n) {
vector<int>count(26,0);
int maxcnt=0;
for(auto c:tasks)
++count[c-'A'];
sort(count.begin(),count.end());
int i=0,time=0;
while(count.back()>0)
{
while(i<=n)
{
if(count.back()==0)break;
if(i<26&&count[25-i]>0)
{
--count[25-i];
}
++time;
++i;
}
i=0;
sort(count.begin(),count.end());
}
return time;
}
};
方法一是每一轮完成后进行依次排序,其实也可以用优先级队列来实现,具体思路与上一种方法并没有太大差异;
方法二:
class Solution {
public:
int leastInterval(vector<char>& tasks, int n) {
vector<int>count(26,0);
for(auto c:tasks)
++count[c-'A'];
priority_queue<int>pr;
for(auto c:count)
if(c>0)pr.push(c);
int i=0,time=0;
while(!pr.empty())
{
vector<int>temp;
i=0;
while(i<=n)
{
if(!pr.empty())
{
if(pr.top()>1)
temp.push_back(pr.top()-1);
pr.pop();
}
++i;
++time;
if(pr.empty()&&temp.size()==0)break;
}
for(auto c:temp)
pr.push(c);
}
return time;
}
};
方法三:仔细分析整个过程发现,完成任务的时间取决与出现次数最多的那个任务
例如:AAABBC n=2
A出现次数最多,我可以直接安排好A为 AxxAxxA, 中间的x可以表示执行其他任务或者等待,直接计算完成任务时间为(3-1)*(2+1)+1
在例如AAABBBCC n=2
这时候A和B出现次数都是最大,安排为AxxAxxAB,完成任务时间为(3-1)(2+1)+2
那么我们可以总结出一个公式:time=(maxcnt-1)(n+1)+cnt,其中maxcnt表示任务出现最多的次数,n表示冷却时间,cnt表示出现了maxcnt次的任务有多少个
最后有特例,比如当n=0时按公式计算结果小于tasks数组长度,这时候直接取数组长度即可
代码如下:
class Solution {
public:
int leastInterval(vector<char>& tasks, int n) {
vector<int>count(26,0);
int maxcnt=0;
for(auto c:tasks)
++count[c-'A'];
sort(count.begin(),count.end());
for(auto c:count)
if(c==count.back())++maxcnt;
int res=(count.back()-1)*(n+1)+maxcnt>tasks.size()?(count.back()-1)*(n+1)+maxcnt:tasks.size();
return res;
}
};

5919

被折叠的 条评论
为什么被折叠?



