leetcode 621. Task Scheduler

来源:互联网 发布:c语言break 编辑:程序博客网 时间:2024/06/05 21:49

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 = 2Output: 8Explanation: 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].
需要注意的是题目中说的:return the least number of intervals,因此我们应该考虑到把次数多的工作先做,这样在做完它等待的n个钟头内可以做其他工作。如 ['A','B','B'],应该返回4,而不是5。

下面是我的解法:theTasks里包含26个大写字母的tasks次数。需要注意的是 之后有对数组进行排序,所以theTasks[0]不一定对应着'A',其余也不一定对应。我们这一题并不需要关心是否字母对应,只关心从大到小的数字。

package leetcode;public class Task_Scheduler_621 {public int leastInterval(char[] tasks, int n) {int[] theTasks=new int[26];int[] needRest=new int[26];int num=tasks.length;for(int i=0;i<num;i++){theTasks[tasks[i]-'A']++;}sortDesc(theTasks, needRest, 0, 25);int result=0;while(num>0){boolean findTaskToDo=false;int i=0;for(i=0;i<26;i++){if(theTasks[i]>0&&needRest[i]==0){findTaskToDo=true;theTasks[i]--;needRest[i]=n;num--;break;}}result++;for(int j=0;j<26;j++){if(j!=i&&needRest[j]>0){needRest[j]--;}}if(findTaskToDo==true){sortDesc(theTasks, needRest, 0, 25);}}return result;}public void sortDesc(int[] tasks,int[] needRest,int left,int right){if(left<right){int low=left;int high=right;int pivot=tasks[low];int pivot2=needRest[low];while(low<high){while(low<high&&tasks[high]<=pivot){high--;}tasks[low]=tasks[high];needRest[low]=needRest[high];while(low<high&&tasks[low]>=pivot){low++;}tasks[high]=tasks[low];needRest[high]=needRest[low];}tasks[low]=pivot;needRest[low]=pivot2;sortDesc(tasks, needRest, left, low-1);sortDesc(tasks, needRest, low+1, right);}}public static void main(String[] args) {// TODO Auto-generated method stubTask_Scheduler_621 t=new Task_Scheduler_621();char[] tasks=new char[]{'A','B','B'};int n=2;System.out.println(t.leastInterval(tasks, n));}}
让我们看看这道题的solutions吧:https://leetcode.com/problems/task-scheduler/solution/

Solution


Approach #1 Using Sorting [Accepted]

使用map数组来储存每个任务的次数。然后,我们根据次数从大到小的顺序来执行任务。每次取前n+1个tasks来执行。如果前n+1个tasks存在,则执行完一个,time就+1。如果前n+1个tasks不存在,即当前剩下的tasks已经小于n+1了,那么还是time+1,这是 idle使得time+1。再次循环前n+1个tasks时,这前n+1个tasks一定是已经休息完了的状态。

Now, the task picked up first after the sorting, will either be the first task picked up in the last iteration(which will now be picked after its cooling time has been finished) or the task picked will be the one which lies at (n+1)^{th}(n+1)th position in the previous descending taskstasks array. In either of the cases, the cooling time won't cause any conflicts(it has been considered implicitly). Further, the task most critical currently will always be picked up which was the main requirement.

Java

public class Solution {    public int leastInterval(char[] tasks, int n) {        int[] map = new int[26];        for (char c: tasks)            map[c - 'A']++;        Arrays.sort(map);        int time = 0;        while (map[25] > 0) {            int i = 0;            while (i <= n) {                if (map[25] == 0)                    break;                if (i < 26 && map[25 - i] > 0) //相当于倒序取数                    map[25 - i]--;                time++;                i++;            }            Arrays.sort(map);        }        return time;    }}

Complexity Analysis

  • Time complexity : O(time)O(time). Number of iterations will be equal to resultant time timetime.

  • Space complexity : O(1)O(1). Constant size array mapmap is used.


Approach #2 Using Priority-Queue [Accepted]

Algorithm

使用一个最大堆(优先级队列),来代替上面方法中 每循环一次都要排序。

我们首先把元素放入map中计算count,再把 >0 的次数放入queuequeue 中。然后,我们开始 pop 出queue 中次数最大的任务,然后执行它,减少它的次数,如果它的次数还大于0,那么将它存入一个暂时的temptemp数组(用来之后再次存入queue)。然后继续做这件事,直到做了n+1次为止(这样一个冷却时间回合已经结束了)。在每次回合之后,我们把 temp 数组中的元素重新放入 queuequeue 。

Java

public class Solution {    public int leastInterval(char[] tasks, int n) {        int[] map = new int[26];        for (char c: tasks)            map[c - 'A']++;        PriorityQueue < Integer > queue = new PriorityQueue < > (26, Collections.reverseOrder());        for (int f: map) {            if (f > 0)                queue.add(f);        }        int time = 0;        while (!queue.isEmpty()) {            int i = 0;            List < Integer > temp = new ArrayList < > ();            while (i <= n) {                if (!queue.isEmpty()) {                    if (queue.peek() > 1)                        temp.add(queue.poll() - 1);                    else                        queue.poll();                }                time++;                if (queue.isEmpty() && temp.size() == 0)                    break;                i++;            }            for (int l: temp)                queue.add(l);        }        return time;    }}

Complexity Analysis

  • Time complexity : O(n)O(n). Number of iterations will be equal to resultant time timetime.

  • Space complexity : O(1)O(1)queuequeue and temptemp size will not exceed O(26).


Approach #3 Calculating Idle slots [Accepted]

Algorithm

如果我们能够知道idle的次数,我们就能知道最终执行的时间。最终执行时间= idle\_slots + Total Number Of Tasksidle_次数+任务的总个数

首先看图1:

Tasks

从图1中可以看出,idle的最大数取决于 (次数最大的任务的次数-1) * 每次的冷却时间 。而idle次数的减少则取决于其他任务的次数。

Java

public class Solution {    public int leastInterval(char[] tasks, int n) {        int[] map = new int[26];        for (char c: tasks)            map[c - 'A']++;        Arrays.sort(map);        int max_val = map[25] - 1, idle_slots = max_val * n;        for (int i = 24; i >= 0 && map[i] > 0; i--) {            idle_slots -= Math.min(map[i], max_val);        }        return idle_slots > 0 ? idle_slots + tasks.length : tasks.length;    }}

Complexity Analysis

  • Time complexity : O(n)O(n). We iterate over taskstasks array only once. (O(n)O(n)).Sorting taskstasks array of length nn takes O\big(26log(26)\big)= O(1)O(26log(26))=O(1) time. After this, only one iteration over 26 elements of mapmap is done(O(1)O(1).

  • Space complexity : O(1)O(1)mapmap array of constant size(26) is used.

Examples:

AAAABBBEEFFGG 3

here X represents a space gap:

Frame: "AXXXAXXXAXXXA"insert 'B': "ABXXABXXABXXA" <--- 'B' has higher frequency than the other characters, insert it first.insert 'E': "ABEXABEXABXXA"insert 'F': "ABEFABEXABFXA" <--- each time try to fill the k-1 gaps as full or evenly as possible.insert 'G': "ABEFABEGABFGA"


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 买了黄牛假票怎么办 火车坐过站了怎么办 被黄牛骗了300怎么办 断奶后乳房有硬块怎么办 断奶了有硬块疼怎么办 断奶时乳房有硬块怎么办 憋奶乳房有硬块怎么办 回奶以后有硬块怎么办 回奶里面有肿块怎么办 回奶时候的硬块怎么办 回奶乳房有硬块怎么办 回奶胀痛有硬块怎么办 回奶期间有硬块怎么办 回奶期间乳房有硬块怎么办 回奶乳房有肿块怎么办 牛犊子出生3天喘怎么办 猪高烧不退不吃怎么办 苹果6刷机失败怎么办 uc能看不能下怎么办 苹果6s铃声太小怎么办 苹果6铃声声音小怎么办 苹果7来电铃声小怎么办 红米手机声音小怎么办 微信安装不上去怎么办 6s无法安装微信怎么办 苹果4微信版本低怎么办 新手机没有微信怎么办 新手机登陆微信怎么办 新号码被注册过怎么办 微信注册不了怎么办啊 苹果4铃声不响怎么办 苹果6黑屏没反应怎么办 苹果7卡机黑屏了怎么办 苹果7手机铃声小怎么办 支付宝发现套现怎么办 空调滴水管断了怎么办 地漏下水管断了怎么办 脸上长白色糠疹怎么办 腋下长白色的毛怎么办 饥荒电羊死光了怎么办 6s储存空间虚满怎么办