leetcode621. Task Scheduler(621. 任务调度器)/贪心

题目:621. 任务调度器

Given a characters array tasks, representing the tasks a CPU needs to do, where each letter represents a different task. Tasks could be done in any order. Each task is done in one unit of time. For each unit of time, the CPU could complete either one task or just be idle.

However, there is a non-negative integer n that represents the cooldown period between two same tasks (the same letter in the array), that is that there must be at least n units of time between any two same tasks.

Return the least number of units of times that 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
There is at least 2 units of time between any two same tasks.

Example 2:

Input: tasks = ["A","A","A","B","B","B"], n = 0
Output: 6
Explanation: On this case any permutation of size 6 would work since n = 0.
["A","A","A","B","B","B"]
["A","B","A","B","A","B"]
["B","B","B","A","A","A"]
...
And so on.

Example 3:

Input: tasks = ["A","A","A","A","A","A","B","C","D","E","F","G"], n = 2
Output: 16
Explanation: 
One possible solution is
A -> B -> C -> A -> D -> E -> A -> F -> G -> A -> idle -> idle -> A -> idle -> idle -> A

Constraints:

  • 1 <= task.length <= 104
  • tasks[i] is upper-case English letter.
  • The integer n is in the range [0, 100].

基本思想:

为了用最少的时间片调度完所有的任务,采取每次调度剩余任务数最多的任务,并且要保证该任务在当前时间下可调度(因为题目中规定,必须间隔n个时间片才能再次调度该任务)。

因此,以时间片进行遍历,执行该任务需要满足如下两个条件:

  • 当前时间下,该任务可以被调度,也就是当前时间大于等于该任务能够被调度的时间。那么调度完该任务后,需要更新下下次调度该任务的时间,即当前时间+n+1
  • 该任务是剩余任务中,剩余次数最多的任务
class Solution {
public:
    
    int leastInterval(vector<char>& tasks, int n) {
        //TODO:统计每个字符出现的次数
        vector<int> temp(26, 0);
        for(auto t : tasks){//保存出现的次数
            temp[t - 'A'] += 100;
        }
        for(int i = 0; i < 26; ++i){//保存字符本身
            if(temp[i])
                temp[i] += i;
        }
        //TODO:构造一个哈希表,将在CPU中最早可存放的时间作为键,将其对应的在原任务中出现的次数作为值(维护一个优先队列)
        map<int, priority_queue<int>> mp;
        for(int i = 0; i < 26; ++i){
            if(temp[i]){
                mp[1].push(temp[i]); 
            }
        }
        int early = 1;//时间片
        while(!mp.empty()){
            int cur_cnt = (mp.begin()->second).top();            
            int cur_time = mp.begin()->first;
            if(cur_time > early){//意味着当前时间片没有能够执行的任务
                early++;
                continue;
            }
            
            //寻找剩余次数最多的元素
            for(auto m : mp){
                if(m.second.top() > cur_cnt && m.first <= early){
                    cur_cnt = m.second.top();
                    cur_time = m.first;
                }
            }
            
            auto cur = mp[cur_time].top(); //对应当前系统时间可存放的元素
            //cout << cur << endl;
            cur -= 100;
            mp[cur_time].pop();
            if(mp[cur_time].size() == 0)
                mp.erase(cur_time);
            if(cur >= 100)
                mp[cur_time + n + 1].push(cur); 
            ++early;
        }
        return early - 1;
    }
};
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页