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:
- The number of tasks is in the range [1, 10000].
- The integer n is in the range [0, 100].
下面是我的解法: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 position in the previous descending tasks 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). Number of iterations will be equal to resultant time time.
Space complexity : O(1). Constant size array map is used.
Approach #2 Using Priority-Queue [Accepted]
Algorithm
使用一个最大堆(优先级队列),来代替上面方法中 每循环一次都要排序。
我们首先把元素放入map中计算count,再把 >0 的次数放入queue 中。然后,我们开始 pop 出queue 中次数最大的任务,然后执行它,减少它的次数,如果它的次数还大于0,那么将它存入一个暂时的temp数组(用来之后再次存入queue)。然后继续做这件事,直到做了n+1次为止(这样一个冷却时间回合已经结束了)。在每次回合之后,我们把 temp 数组中的元素重新放入 queue 。
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). Number of iterations will be equal to resultant time time.
Space complexity : O(1). queue and temp size will not exceed O(26).
Approach #3 Calculating Idle slots [Accepted]
Algorithm
如果我们能够知道idle的次数,我们就能知道最终执行的时间。最终执行时间= idle_次数+任务的总个数.
首先看图1:
从图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). We iterate over tasks array only once. (O(n)).Sorting tasks array of length n takes O(26log(26))=O(1) time. After this, only one iteration over 26 elements of map is done(O(1).
Space complexity : O(1). map 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"
- LeetCode 621. Task Scheduler
- 【LeetCode】621. Task Scheduler
- [LeetCode] 621. Task Scheduler
- Leetcode 621. Task Scheduler
- [leetcode]621. Task Scheduler
- leetcode 621. Task Scheduler
- Leetcode:621. Task Scheduler
- [LeetCode]621. Task Scheduler
- leetcode 621. Task Scheduler
- Leetcode 621. Task Scheduler
- leetcode 621. Task Scheduler
- leetcode 621. Task Scheduler (贪心)
- leetcode 621 Task Scheduler
- [Leetcode 621] Task Scheduler
- [leetcode] 621 Task Scheduler
- LeetCode Task Scheduler
- LeetCode-Task Scheduler
- LeetCode:Task Scheduler
- linux常用命令小教程(系统管理类)
- 关于vscode编辑器缩进的问题
- 注解实现spring整合quartz,定时执行service层方法,解决无法注入问题
- java函数实现进制转换与java实现八进制到十进制的转换(百练OJ:2735:八进制到十进制)
- docker run命令详解-yellowcong
- leetcode 621. Task Scheduler
- ubuntu16.04配置Lamp环境(搭建linux+apache+mysql+php7环境
- Mybatis插入空值报错
- Git 工作区、暂存区
- 单例模式详解
- c c++中的extern和static总结
- 关于Ubuntu16.04 中wine QQ 国际版无法输入中文
- 如何在一个div中使其子div居中
- 解决Ubuntu Windows共存 8个小时时差问题