刷题621. Task Scheduler

一、题目说明

题目621. Task Scheduler,给定一列字符列表(A~Z)表示CPU执行的任务,可以任意执行,每个任务在1单位时间执行完成,CPU在一个单位时间内可以执行一个任务,或者处于IDEL状态。两个相同类型任务必须有n单位冷却时间。计算任务执行所需的最少时间。

二、我的解答

看到这个题目,我能想到的就是,统计每个任务的次数,然后从次数从高到低排序,放入数组中。向将A插入数组

先把A插入数组中, 变成 A $ $ A $ $ A $ $ A,再将B插入数组中A B $ A B $ A B $ AB,返回数组的长度即可。下面的解答是错误的:

class Solution{
	public:
		//该解答错误在于每次取出数量最高的任务,全部安排好。继续取数量最高的任务不对 
		//正确的解答是每次取出n+1个任务 
		int leastInterval(vector<char>& tasks,int n){
			if(tasks.size()<1) return 0;
			if(tasks.size()<2) return 1;
			//if(n==1) return tasks.size();
			
			res.clear();
			ump.clear();
			
			//统计每个任务出现的次数 
			for(int i=0;i<tasks.size();i++){
				ump[tasks[i]]++;
			}
			
			for(unordered_map<char,int>::iterator iter=ump.begin();iter!=ump.end();iter++){
				cout<<iter->first<<"="<<iter->second<<"->";
			}
			cout<<"
";

			bool first = true;
			while(ump.size()>0){
				char curr = findMaxNum(ump);
				int num = ump[curr];
				ump.erase(curr);
				if(first){
					//第一个任务 
					while(num>1){
						res.push_back(curr);
						for(int j=0;j<n;j++){
							res.push_back('$');
						}
						num--;
					}
					res.push_back(curr);
					first = false;					
				}else{
					//其他任务 填空 
					int tmp = 1;
					while(num>0 && tmp<res.size()){
						if(res[tmp]=='$'){
							res[tmp] = curr;
							tmp = tmp + n + 1;
							num--;
						}else{
							tmp++;
						}
					}
					if(num<1){
						continue;
					}else{
						if(tmp>res.size()){
							while(tmp>res.size()){
								res.push_back('$');
							}
						}
						res.push_back(curr);
						num--;
					}
					while(num>0){
						for(int j=0;j<n;j++){
							res.push_back('$');
						}
						res.push_back(curr);
						num--;
					}
				}
			}
			for(int t=0;t<res.size();t++){
				cout<<res[t]<<"->";
			}
			cout<<"
";
			return res.size();
		}
	private:
		vector<char> res;
		unordered_map<char,int> ump;
		char findMaxNum(unordered_map<char,int>& ump){
			int maxNum=0;
			char maxChar;
			for(unordered_map<char,int>::iterator iter=ump.begin();iter!=ump.end();iter++){
				if(iter->second > maxNum){
					maxChar = iter->first;
					maxNum = iter->second;
				}
			}
			return maxChar;
		}
};

正确的应该是:

class Solution{
	public:
		//采用优先级队列,次数最高的在前面 
		int leastInterval(vector<char>& tasks,int n){
			int res = 0;
			int cycle = n+1;
			unordered_map<char,int> ump;
			priority_queue<int> q;
			for(char c: tasks){
				ump[c]++;
			}
			for(auto a:ump){
				q.push(a.second);
			}
			
			while(! q.empty()){
				int cnt = 0;
				vector<int> t;
				//每次取出n+1个元素 
				for(int i=0;i<cycle;i++){
					if(! q.empty()){
						t.push_back(q.top());
						q.pop();
						++cnt;
					}
				}
				for(int d: t){
					if(--d >0){
						q.push(d);
					}
				}
				res += q.empty() ? cnt : cycle;
			}
			return res;
		}
};

性能如下:

Runtime: 148 ms, faster than 25.51% of C++ online submissions for Task Scheduler.
Memory Usage: 19.3 MB, less than 29.79% of C++ online submissions for Task Scheduler.

三、优化措施

用公式解答最方便:网上很多解答,我就不注解了。

class Solution{
	public:
		int leastInterval(vector<char>& tasks,int n){
			unordered_map<char,int> ump;
			int count = 0,same=0,res = 0;
			for(char c: tasks){
				ump[c]++;
				count = max(count,ump[c]);
			}
			for(auto c: ump){
				if(c.second == count){
					++same;
				}
			}
			res = (count-1)*(n+1) + same;
			return max(res,(int)tasks.size());
		}
};

性能如下:

Runtime: 68 ms, faster than 62.56% of C++ online submissions for Task Scheduler.
Memory Usage: 9.8 MB, less than 78.72% of C++ online submissions for Task Scheduler.
所有文章,坚持原创。如有转载,敬请标注出处。
原文地址:https://www.cnblogs.com/siweihz/p/12309633.html