1.解析
题目大意,求解最优的系统调度时间。要求,两个相同任务之间的时间间隔不能小于n
2.分析
这道题没什么套路,我个人感觉还是比较难的,尤其题目意思,解题思路也不是很容易想到。我最初看到求解最值,我以为是动态规划。参考 @Grandyang博主的思路,讲解的很清晰。
我们可以先看一个例子,例如:['A', 'B', 'A', 'B','A','B','C'] n = 2
既然要达到最优,我们就希望系统休息的时间越短越好。故那个任务出现的次数多,那么谁就排在前面,采用数组进行统计每个任务出现的次数,优先先安排出现次数多的
'A''B'- 'A''B'- 'A''B'
即按照块进行划分,如果任务出现次数最多的存在多个,那么我们就将其排在一块,设mx为所出现次数最多的个数,mx_Cnt为相同的个数(最多的),如上所示,'A'任务出现的次数和'B'任务出现的次数都为3,故mx = 3, mx_Cnt = 2, 所划分的模块的个数partSize = mx - 1 = 2;
每个模块还可以继续填充任务的个数用emptySlot表示,emptySlot = n + 1 - mx_Cnt = 1;
还未填充的任务可以用:idles = 所有任务的个数(tasks.size()) - 已经填充的任务(mx * mx_Cnt )
所以系统执行完所花的时间间隔为:所有任务的个数 + 还剩下的空格(emptySlot -idles )
语言有点难描述,具体实现参考如下:
class Solution {
public:
int leastInterval(vector<char>& tasks, int n) {
int mx = 0, mx_Cnt = 0; //mx---出现的最多任务个数,mx_cnt---最多任务的个数
vector<int> count(26, 0);
for (auto task : tasks){ //统计最多任务的个数以及对应的数量
if (++count[task-'A'] == mx){
++mx_Cnt;
}
else if (count[task-'A'] > mx){
mx = count[task-'A'];
mx_Cnt = 1;
}
}
int partSize = mx - 1; //模块的个数
int partEmpty = n + 1 - mx_Cnt; //还未填充任务的个数
int emptySlot = partSize * partEmpty; //可以继续填充的任务个数
int leaveTasks = tasks.size() - mx * mx_Cnt; //待填充的任务个数
int idles = max(0, emptySlot - leaveTasks);
return tasks.size() + idles;
}
};