每天6道题之第十七题:任务调度器(桶思想)

前言

在这里插入图片描述

题目描述

给定一个用字符数组表示的CPU需要执行的任务列表。其中包含使用大写的A-Z字母表示的26种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以再1个单位时间内执行完,CPU在任何一个单位时间内都可以执行一个任务,或者在待命状态。
然而,两个 相同种类 的任务之间必须有长度为整数 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU
在执行不同的任务,或者在待命状态。 你需要计算完成所有任务所需要的 最短时间

题目解析

先看力扣上的一个示例:
在这里插入图片描述
也就是说所有任务的最短时间应该是尽量相隔的任务是不重复的,因为如果一旦相隔的任务一样中间就会有待命冷却时间,这样的话就会导致总的时间变长。

解题思路

现在知道了我们要尽量使相隔的任务不重复,那我们就考虑怎么去实现,题解有一种思想是“填桶思想”,我觉得很有意思:
“填桶”的基本思想就是首先划定最小桶区域,(1)以需要执行任务最多的次数作为行(也就是相同字符的次数作为行),以n+1作为列。
(2)然后从次数最多的任务开始依次从上往下,从左到右进行填充
(3)有可能发生两种情况:填充不满和填充区域不够:
①填充不满:对于填充不满的情况,必须有空闲单位时间在等待,如图:
在这里插入图片描述

这种情况下需要的执行时间是:
(n+1)*(max-1)+max count
这里的max count指的是有几个数量都是max的字符,也是最后一个桶的任务数量

②填充区域不够:按照填充顺序继续填充即可。
在这里插入图片描述

在这种情况下,需要的执行时间就是:
tasks.length(),这个很容易理解,如果填充的刚刚好,那说明现在相同任务的间隔都满足n,此时就不需要等待时间,如果再继续填充更不用等待了。

思想了解了,接下来的就好办了:
我们只需要记录两个数:
1、纪录最大任务量数N,看一下任务数量并列最多的任务有几个,也就是最后一个桶的任务数X:最后计算num1=(N-1)*(n+1)+X
2、num2=task2.size()
输出其中较大值即可,因为存在空闲时间的话也就是填不满的时候肯定是num1大,不存在空闲时间的话肯定是num2>=num1.

leastInterval代码实现

int leastInterval(vector<char> &tasks,int n){
	int len=tasks.size();
	if(n==0) return len;
	vector<int> vec(26);
	int N=0;
	for(char c:tasks){
	//用来记录不同任务字符的个数
		++vec[c-'A'];
		N=max(vec[c-'A'],N);
	}
	ine res=(N-1)*(n+1);
	for(int v:vec){
		if(v ==N){
			res++;
		}
	}
	return max(res,len);
}

完整代码

#include<iostream>
#include<stack>
#include<vector>
using namespace std;

class Solution{
	public:
		int leastInterval(vector<char> &tasks,int n){
			int len=tasks.size();
			if(n==0) return len;
			vector<int> vec(26);
			int N=0;
			for(char c:tasks){
			//用来记录不同任务字符的个数
				++vec[c-'A'];
				N=max(vec[c-'A'],N);
			}
			int res=(N-1)*(n+1);
			for(int v:vec){
				if(v ==N){
					res++;
				}
			}
		return max(res,len);
		}
};

int main(){
	vector<char> tasks;
	int len;
	char data;
	cin>>len;
	for(int i=0;i<len;i++){
		cin>>data;
		tasks.push_back(data);
	}
	int n;
	cin>>n;
	int res=Solution().leastInterval(tasks,n);
	//interval:间隔 
	cout<<res<<endl;
	return 0;
	
	
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值