621. 任务调度器
2020-12-05 01:22 woshihuangrulin 阅读(95) 评论(0) 编辑 收藏 举报给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。在任何一个单位时间,CPU 可以完成一个任务,或者处于待命状态。
然而,两个 相同种类 的任务之间必须有长度为整数 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。
你需要计算完成所有任务所需要的 最短时间 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/task-scheduler
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
拿到这道题目后发现最优的应该是尽量相隔的任务是不重复的,可以使用优先队列和数组的形式来保证相邻的字符都是不重复的,当字符种类小于最小间隔时需要特殊处理,即在时间上加上等待的那部分,比较难处理的是要考虑最后添加的字符如果短于n+1,需要将尾部的等待的那部分时间去除掉,具体代码如下:
class Solution { public: int leastInterval(vector<char>& tasks, int n) { if (n == 0) { return tasks.size(); } int k = n+1; vector<int> tasks_vec(26, 0); for (auto t : tasks) { tasks_vec[t - 'A']++; } auto func = [&](char a, char b) { return tasks_vec[a-'A'] < tasks_vec[b-'A']; }; priority_queue<char, vector<char>, decltype(func)> prio_q(func); for (int i=0; i<tasks_vec.size(); i++) { if (tasks_vec[i] > 0) { prio_q.push(static_cast<char>(i + 'A')); } } int min_steps = 0; vector<char> result; while(prio_q.size()>0) { result.clear(); if (prio_q.size() >= k) { for (int i=0; i<k; i++) { auto c = prio_q.top(); prio_q.pop(); tasks_vec[c-'A']--; min_steps++; result.push_back(c); } for (auto c : result) { if (tasks_vec[c-'A'] > 0) { prio_q.push(c); } } } else { int size = prio_q.size(); for (int i=0; i<size; i++) { auto c = prio_q.top(); prio_q.pop(); tasks_vec[c-'A']--; min_steps++; result.push_back(c); } for (auto c : result) { if (tasks_vec[c-'A'] > 0) { prio_q.push(c); } } min_steps += k-size; } } if (result.size() < k) { min_steps -= k-result.size(); } return min_steps; } };