|
| 1 | +# 621. Task Scheduler |
| 2 | + |
| 3 | +## Heap solution |
| 4 | +- Runtime: O(Nlog(U)) |
| 5 | +- Space: O(U) |
| 6 | +- N = Number of elements in array |
| 7 | +- U = Number of unique elements in array |
| 8 | + |
| 9 | +This question requires a greedy algothrim. |
| 10 | +We want to use the task that occurs the most first so we can reduce the amount of idle time there is. |
| 11 | +With that, a heap can help us find those set of tasks. |
| 12 | + |
| 13 | +However, there is one tricky edge case that I've noted below. |
| 14 | +If you had an input will many tasks that occur the same amount of times and one that occurs many times. |
| 15 | +Its actually bad to start all the tasks in the first go around. |
| 16 | +Its better to interweave them between the one task that occurs many times to reduce idle times. |
| 17 | + |
| 18 | +**Important edge case to consider** |
| 19 | +``` |
| 20 | +Input: |
| 21 | +["A","A","A","A","A","A","B","C","D","E","F","G"] |
| 22 | +2 |
| 23 | +
|
| 24 | +Wrong Answer: |
| 25 | +ABCDEFGA--A--A--A--A |
| 26 | +20 |
| 27 | +
|
| 28 | +Correct Answer: |
| 29 | +ABCADEAFGA--A--A |
| 30 | +16 |
| 31 | +``` |
| 32 | + |
| 33 | +``` |
| 34 | +from collections import Counter |
| 35 | +
|
| 36 | +class Solution: |
| 37 | + def leastInterval(self, tasks: List[str], n: int) -> int: |
| 38 | + n_intervals = n_idles = 0 |
| 39 | + ch_to_count = Counter(tasks) |
| 40 | + max_heap = [-count for count in ch_to_count.values()] |
| 41 | + heapq.heapify(max_heap) |
| 42 | + while len(max_heap) > 0: |
| 43 | + popped_items = list() |
| 44 | + for _ in range(n+1): |
| 45 | + if len(max_heap) > 0: |
| 46 | + popped_items.append(heapq.heappop(max_heap)) |
| 47 | + else: |
| 48 | + break |
| 49 | + |
| 50 | + n_intervals += len(popped_items) + n_idles |
| 51 | + if len(popped_items) < n: |
| 52 | + n_idles = n - len(popped_items) + 1 |
| 53 | + elif len(popped_items) > n: |
| 54 | + n_idles = 0 |
| 55 | + else: # len(popped_items) == n |
| 56 | + n_idles = 1 |
| 57 | + |
| 58 | + popped_items = [count+1 for count in popped_items if count+1 != 0] |
| 59 | + max_heap += popped_items |
| 60 | + heapq.heapify(max_heap) |
| 61 | + |
| 62 | + return n_intervals |
| 63 | +``` |
0 commit comments