LeetCode 621. Task Scheduler
方法一:Priority Queue
由于相同的间隔至少为n,所以可以把 n+1 看作一组。利用greedy的思想,每次按照剩余的frequency来填充当前 n+1 个time slot。注意需要一个临时的数组记录新的frequency,等 n+1 个time slot分配完以后再放入优先队列中。
这种方法的本质就是利用greedy做simulation。
class Solution { public: int leastInterval(vector<char>& tasks, int n) { priority_queue<int> q; // frequency of remaining tasks unordered_map<char,int> count; for (char task:tasks) ++count[task]; for (auto x:count) q.push(x.second); int res=0; while (!q.empty()){ // assign to n+1 slots according to frequency int slots=n+1; vector<int> new_freq; while (slots){ if (q.empty()){ if (new_freq.size()==0) return res; else{ res += slots; // we need insert idles break; } }else{ int cur=q.top(); q.pop(); if (cur-1>0) new_freq.push_back(cur-1); --slots; ++res; } } for (auto x:new_freq) q.push(x); } return res; } };
方法二:Calculating Idle Slots
同样是利用greedy的方法,但是计算idle slot。如图所示,最后一行一定没有空的slot。可能是idle的地方只可能是 (max_count-1)*n [每行第一个一定有task,否则这一行就不存在了]。然后我们要找到有多少需要allocate的task。对于每种task,如果其frequency和最大frequency一样,由于最后一行我们没有计算在内,所以要少一个slot。别的比最大frequency小的task,我们直接减去即可。
如果最后得到的idle slot结果为负,就当做0处理。
class Solution { public: int leastInterval(vector<char>& tasks, int n) { vector<int> count(26,0); for (char task:tasks) ++count[task-'A']; sort(count.begin(),count.end()); int max_freq=count[25]; int idle=(max_freq-1)*n; for (int i=0;i<=24;++i){ int freq=count[i]; if (freq==max_freq) idle-=(max_freq-1); else idle-= freq; } return tasks.size() + (idle>0?idle:0); } };
Reference