暴力模拟 哈希计数存储 用哈希表初始化容器 容器存储自定义结构体 每轮循环结构体自定义排序 按每类任务的剩余次数降序排序 优先选择剩余次数最大的任务
struct zifu {//保存一种任务种类,num存储剩余任务次数
char fu;
int num;
};
static bool cmp(const zifu &a, const zifu &b) {//自定义排序方式,以任务次数降序排序
return a.num > b.num;
}
int leastInterval(vector<char>& tasks, int n) {
if (n == 0) return tasks.size();
unordered_map<char, int>mymap;//哈希存储字符和任务次数
vector<zifu>mv;//用容器来对剩余任务自定义排序
for (int i = 0; i < tasks.size(); i++) {//存入哈希表
mymap[tasks[i]]++;
}
for (auto it = mymap.begin(); it != mymap.end(); it++) {//通过哈希表建立容器
zifu x;
x.fu = it->first;
x.num = it->second;
mv.push_back(x);
}
int kind = mymap.size(), time = 0;//kind表示剩余任务种类数
//每轮循环要优先选择剩余次数最多的任务种类,这样才能达到最少时间,这是关键,这样才能最大化利用时间空隙
while (kind > 0) {
sort(mv.begin(), mv.end(), cmp);//每轮让剩余次数最多的任务排在前面
if (kind > n) {//剩余种类个数大于间隔时间,可以先取n+1种类取一个任务做 ,注意不是取所有种类取一个任务做,而是取最小要求的n+1个,这样可以让time达到最小
//PS:剩余种类个数等于间隔时间是不行的 此时需要等待一个单位时间才能进行下一轮 临界条件注意区分
int i = 0,j=0;//i为本次for循环中剩余次数减为0的种类数
for (auto it = mv.begin(); j<=n;j++) {//取n+1个任务来做
(*it).num--;
if ((*it).num == 0) {
it = mv.erase(it);
i++;
}
else it++;
}
time += (n + 1);
kind -= i;
}
else {//剩余种类个数小于或等于间隔时间
int i = 0;
for (auto it = mv.begin(); it != mv.end();) {
(*it).num--;
if ((*it).num == 0) {
it = mv.erase(it);
i++;
}
else it++;
}
time += (n + 1);
kind -= i;
if (kind == 0) time = time - (n + 1) + i;//如果这是最后一轮,那么time加多了,因为把任务做完就不需要等待了,time += n + 1;多算上了等待时间
}
}
return time;
}