代码改变世界

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