Reference
[1] https://leetcode.com/articles/task-scheduler/
[2] https://www.hackerrank.com/challenges/task-scheduling/problem (hackerrank or interviewstreet)
[3] https://github.com/ningke/tasksched
[4] http://p--np.blogspot.co.uk/2011/07/segment-tree.html
[5] segment tree https://www.cnblogs.com/xiaoyao24256/p/6590885.html
[6] binary indexed tree https://www.cnblogs.com/whensean/p/6851018.html
1.
You have a long list of tasks that you need to do today. Task i is specified by the deadline by which you have to complete it (Di) and the number of minutes it will take you to complete the task (Mi). You need not complete a task at a stretch. You can complete a part of it, switch to another task and then switch back.
You've realized that it might not actually be possible complete all the tasks by their deadline, so you have decided to complete them so that the maximum amount by which a task's completion time overshoots its deadline is minimized.
Solution: The key insight is that the task with a later deadline MUST be completed later than a task with an earlier deadline - regardless how you break up the tasks. Otherwise, the first task (the one with an earlier deadline) will overshoot its own deadline by more than the second task overshoots its deadline. So we can essentially just sort the tasks by their deadline and complete them in that order. The problem description about breaking up tasks are just there to confuse you.
2.
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:
- The number of tasks is in the range [1, 10000].
- The integer n is in the range [0, 100].
The tasks with the currently maximum number of outstanding (pending)instances will contribute to a large number of idle cycles in the future, if not executed with appropriate interleavings with the other tasks. Thus, we need to re-execute such a task as soon as its cooling time is finished.
Thus, based on the above ideas, firstly, we obtain a count of the number of instances of each task in mapmaparray. Then, we start executing the tasks in the order of descending number of their initial instances. As soon as we execute the first task, we start its cooling timer as well(ii). For every task executed, we update the pending number of instances of the current task. We update the current time, timetime, at every instant as well. Now, as soon as the timer, ii's value exceeds the cooling time, as discussed above, we again need to consider the task with the largest number of pending instances. Thus, we again sort the taskstasks array with updated counts of instances and again pick up the tasks in the descending order of their number of instances.
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 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.
We stop this process, when the pending instances of all the tasks have been reduced to 0. At this moment, timetime gives the required result.
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; } }