zoukankan      html  css  js  c++  java
  • 621. Task Scheduler

    问题描述:

    Given a char array representing tasks CPU need to do. It contains capital letters A to Z where different letters represent different tasks.Tasks could be done without original order. Each task could be done in one interval. For each interval, CPU could finish one task or just be idle.

    However, there is a non-negative cooling interval n that means between two same tasks, there must be at least n intervals that CPU are doing different tasks or just be idle.

    You need to return the least number of intervals the CPU will take to finish all the given tasks.

    Example 1:

    Input: tasks = ["A","A","A","B","B","B"], n = 2
    Output: 8
    Explanation: A -> B -> idle -> A -> B -> idle -> A -> B. 

    Note:

    1. The number of tasks is in the range [1, 10000].
    2. The integer n is in the range [0, 100].

    解题思路:

    我们可以首先统计每个人物出现的次数,然后首先安排次数最多的任务。

    我们可以用优先队列来帮助我们进行选择次数最多的任务。

    因为至少要隔n个时间单位,说明在n+1个时间单位内不能有重复,所以可以不断从队列里取出。

    选取万一个block(也就是n+1)个时间单位后,我们要将新的出现次数重新压入优先队列中。

    所以可以用一个数组来存储。

    看了Grandyang整理的方法中还有别的更快的方法。

    这里只copy了一个

    代码:

    用优先队列的方法:

    class Solution {
    public:
        int leastInterval(vector<char>& tasks, int n) {
            unordered_map<char,int> m;
            for(char c:tasks){
                m[c]++;
            }
            priority_queue<int> q;
            for(auto p : m){
                q.push(p.second);
            }
            int ret = 0;
            while(!q.empty()){
                int cnt = 0;
                vector<int> temp;
                for(int i = 0; i <= n; i++){
                    if(!q.empty()){
                        temp.push_back(q.top());
                        q.pop();
                        cnt++;
                    }
                }
                for(int i = 0; i < temp.size(); i++){
                    if(--temp[i] > 0)
                        q.push(temp[i]);
                }
                ret += q.empty() ? cnt : n+1;
            }
            return ret;
        }
    };

    更快的方法:

    对于整个安排来说,以出现次数最多(max次)的字母开头后面跟着其他字母的长度为n+1的block会出现max-1次。

    因为我们不能保证最后一个block一定会被填满。

    最后一个block中应该存着出现次数等于max次的任务。

    注意最后返回的是

    max(len, (mx - 1) * (n + 1) + 25 - i)

    因为我们的排列长度至少要等于给我们的任务个数

    class Solution {
    public:
        int leastInterval(vector<char>& tasks, int n) {
            vector<int> cnt(26, 0);
            for (char task : tasks) {
                ++cnt[task - 'A'];
            }
            sort(cnt.begin(), cnt.end());
            int i = 25, mx = cnt[25], len = tasks.size();
            while (i >= 0 && cnt[i] == mx) --i;
            return max(len, (mx - 1) * (n + 1) + 25 - i);
        }
    };
  • 相关阅读:
    用List绑定GridView的简单辅助类
    宋忠玲(帮读者名字作诗)
    [转帖]每天看一遍,释怀所有难过
    30岁,我们怎么赢?
    柴门远望
    创业,不要被那些成功人士所忽悠
    一只海燕飞过来
    成功者都在用的“成功咒语”
    诗歌复兴
    游熊猫基地有感
  • 原文地址:https://www.cnblogs.com/yaoyudadudu/p/9192722.html
Copyright © 2011-2022 走看看