力扣621. 任务调度器 模拟法

暴力模拟 哈希计数存储 用哈希表初始化容器 容器存储自定义结构体 每轮循环结构体自定义排序 按每类任务的剩余次数降序排序 优先选择剩余次数最大的任务

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值