关闭

LeetCode 621. Task Scheduler

标签: leetcode
1057人阅读 评论(0) 收藏 举报
分类:

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+1的环。cycle = n + 1. 如果这cycle个坑,必须由不同的task来填。如果没有这么多种类的task,那么剩下的坑cpu就只能空转
  • 那么填坑的时候使用哪些task那,我们尽可能的使用出现次数多的task 因为task不能重复,我们需要尽量使用其他的task来隔开出现次数最多的task,否则就要用idle来隔开他们。
  • 算法的思路就是首先记录出每个task出现的次数,然后把这些次数记录到一个priority_queue中,因为我们只需要知道次数就行了,所以不用再管task的名称。priority_queue默认是大顶堆,也就是出现次数多的task会先出队列。每次遍历时,我们把pq中的task全部出队列,如果这时候cycle被填满了,那么就把task出现的次数全部减1 再添加到pq中去,总的运行时间需要cycle个cpu运转周期;如果cycle没有填满,那么说明需要补充一部分idle来填坑,运行时间同样增长cycle个cpu运转周期。
  • 这里有两点需要注意:(1)把task出现次数添加会pq的时候,需要判断这一轮使用了一个task之后,该task剩余次数是否为0,如果为0,就不能再添加回去了,说明他已经调度完了。(2)如果在这一个cycle完成之后,发现没有task被重新添加到pq中去,说明所有的task都被调度完了,这一次的调度是最后一次,那么只需要添加实际的调度时间,而不是cycle个CPU运转周期。
class Solution {
public:
    int leastInterval(vector<char>& tasks, int n) {
                map<char, int> m;
        for (int i = 0; i < tasks.size(); ++i) {
            m[tasks[i]]++;
        }
        priority_queue<int> pq;
        for (auto ite : m){
            pq.push(ite.second);
        }
        int cycle = n + 1, ret = 0;
        while(!pq.empty()){
            vector<int> tmp;
            int time = 0;
            for (int i = 0; i < cycle; ++i) {
                if (!pq.empty()){
                    tmp.push_back(pq.top());
                    pq.pop();
                    time++;
                }
            }

            for (auto cnt : tmp){
                int remainCnt = cnt - 1;
                if(remainCnt > 0)pq.push(remainCnt);
            }
            if(pq.empty()) ret += time;//如果是最后一次调度,不在需要idle来填充
            else ret += cycle;
        }
        return ret;
    }
};
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:34485次
    • 积分:1373
    • 等级:
    • 排名:千里之外
    • 原创:107篇
    • 转载:0篇
    • 译文:0篇
    • 评论:3条
    博客专栏
    联系我
    QQ: 531267557