Caren
July 27, 2018
64

# Greedy - Session 2

July 27, 2018

## Transcript

2. ### Task Scheduler (Continued) 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 ﬁnish 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 ﬁnish 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.
3. ### Task Scheduler (Continued) Have a size 26 array coolDownTimeLeft, each

index represents the cool down time needed for a particular task. Iterate through each task. When we want to try and schedule a task to run, check the array to see if that’s allowed. Update coolDownTimeLeft after every iteration [A, A, B, C]   schedule A - > [2, 0, 0 .. 0]  try to schedule A, can’t. schedule B instead -> [1, 2, 0 .. 0]  try to schedule A, can’t. schedule C instead -> [0, 1, 2 .. 0]  try to schedule A again -> [2, 0, 1, 0]  A -> B -> C -> A
4. ### Task Scheduler (Continued) Have a size 26 array coolDownTimeLeft, each

index represents the cool down time needed for a particular task. Iterate through each task. When we want to try and schedule a task to run, check the array to see if that’s allowed. Update coolDownTimeLeft after every iteration Inefﬁcient because:  1) We have to remove / mark tasks from the array when it’s scheduled.  2) We have to repeatedly check if we can run a task  3) we might end up scheduling frequent tasks in the end, which would cause us to use up unnecessary idle time.
5. ### Task Scheduler (Continued) Biggest efﬁciency problem:   If a certain

type of task has a lot of instances, we want to run those instances as soon as we can
6. ### Task Scheduler (Continued) Biggest efﬁciency problem:   If a certain

type of task has a lot of instances, we want to run those instances as soon as we can IE :   If we have A A A A A A A B C D   and cool down time = 2  We don’t want the run sequence to be:  A B C D A idle idle A idle idle …    We want it to be  A B C A D idle A idle idle A …
7. ### Task Scheduler (Continued) Biggest efﬁciency problem:   If a certain

type of task has a lot of instances, we want to run those instances as soon as we can IE :   If we have A A A A A A A B C D   and cool down time = 2  We don’t want the run sequence to be:  A B C D A idle idle A idle idle …    We want it to be  A B C A D idle A idle idle A … What should we do?
8. ### Task Scheduler (Continued) Biggest efﬁciency problem:   If a certain

type of task has a lot of instances, we want to run those instances as soon as we can Sort by most instances ﬁrst so those can run ﬁrst
9. ### Task Scheduler (Continued) Biggest efﬁciency problem:   If a certain

type of task has a lot of instances, we want to run those instances as soon as we can Sort by most instances ﬁrst so those can run ﬁrst  BUT as we ﬁgured out previously, we can’t just run the most   common task ﬁrst and wait till to end to run the last   instances  IE : A A A A B C -> sorted  We don’t want to run A B C A A A A
10. ### Task Scheduler (Continued) Biggest efﬁciency problem:   If a certain

type of task has a lot of instances, we want to run those instances as soon as we can Sort by most instances ﬁrst so those can run ﬁrst  BUT as we ﬁgured out previously, we can’t just run the most   common task ﬁrst and wait till to end to run the last   instances  So we should be more efﬁcient and sort again after a cool  down period has passed. IE after we’ve gone through a  ‘cycle’
11. ### Task Scheduler (Continued) Biggest efﬁciency problem:   If a certain

type of task has a lot of instances, we want to run those instances as soon as we can Sort by most instances ﬁrst so those can run ﬁrst  BUT as we ﬁgured out previously, we can’t just run the most   common task ﬁrst and wait till to end to run the last   instances  So we should be more efﬁcient and sort again after a cool  down period has passed. But also, how do we even sort?? The tasks are just letters?
12. ### Task Scheduler (Continued) Biggest efﬁciency problem:   If a certain

type of task has a lot of instances, we want to run those instances as soon as we can Sort by most instances ﬁrst so those can run ﬁrst  BUT as we ﬁgured out previously, we can’t just run the most   common task ﬁrst and wait till to end to run the last   instances  So we should be more efﬁcient and sort again after a cool  down period has passed. But also, how do we even sort?? The tasks are just letters?  Our ﬁrst idea was to put tasks and their instances in a HashMap. But if we put tasks an their instances in an array, we can more easily sort them
13. ### Task Scheduler (Continued) Sorting tasks Given input : B B

B D A B B C A A Z C , cool down time = 2  3 A’s, 5 B’s, 2 C’s, 1 D, 1 Z 3 5 2 1 0 0 0 0 0 … 1 <- size 26 array (26 letters in alphabet)
14. ### Task Scheduler (Continued) Sorting tasks Given input : B B

B D A B B C A A Z C , cool down time = 2  3 A’s, 5 B’s, 2 C’s, 1 D, 1 Z 3 5 2 1 0 0 0 0 0 … 1 <- size 26 array (26 letters in alphabet)    First …. sort tasks by frequency  5 3 2 1 1 0 0 0 …
15. ### Task Scheduler (Continued) Sorting tasks Given input : B B

B D A B B C A A Z C , cool down time = 2  3 A’s, 5 B’s, 2 C’s, 1 D, 1 Z 3 5 2 1 0 0 0 0 0 … 1 <- size 26 array (26 letters in alphabet)    First …. sort tasks by frequency  5 3 2 1 1 0 0 0 …    First iteration (cool down time = 2)  Do the task that has 5 instances  Now our array looks like … 4 3 2 1 1 0 0 …
16. ### Task Scheduler (Continued) Sorting tasks Given input : B B

B D A B B C A A Z C , cool down time = 2  3 A’s, 5 B’s, 2 C’s, 1 D, 1 Z    First iteration (cool down time = 2)  Do the task at index 0   Now our array looks like … 4 3 2 1 1 0 0 …     Second iteration ( cool down time = 1)  Do the task in at index 1   Now our array looks like … 4 2 2 1 1 0 0 …
17. ### Task Scheduler (Continued) Sorting tasks Given input : B B

B D A B B C A A Z C , cool down time = 2  3 A’s, 5 B’s, 2 C’s, 1 D, 1 Z    First iteration (cool down time = 2)  Do the task at index 0   Now our array looks like … 4 3 2 1 1 0 0 …     Second iteration ( cool down time = 1)  Do the task in at index 1   Now our array looks like … 4 2 2 1 1 0 0 … Third iteration (cool down time = 0)   Do the task at index 2. Array is now … 4 2 1 1 1 0 0 …
18. ### Task Scheduler (Continued) Sorting tasks Given input : B B

B D A B B C A A Z C , cool down time = 2  3 A’s, 5 B’s, 2 C’s, 1 D, 1 Z Third iteration (cool down time = 0)   Do the task at index 2. Array is now … 4 2 1 1 1 0 0 … Now our cool time down is 0.   Let’s move pointer index back to 0 (ie schedule the task at index 0)  Now our array looks like … 3 2 1 1 1 0 0
19. ### Task Scheduler (Continued) Sorting tasks Given input : B B

B D A B B C A A Z C , cool down time = 2  3 A’s, 5 B’s, 2 C’s, 1 D, 1 Z Third iteration (cool down time = 0)   Do the task at index 2. Array is now … 4 2 1 1 1 0 0 … Now our cool time down is 0.   Let’s move pointer index back to 0 (ie schedule the task at index 0)  Now our array looks like … 3 2 1 1 1 0 0 Does this always work? Are we missing anything?
20. ### Task Scheduler (Continued) Sorting tasks Given input : B B

B D A B B C A A Z C , cool down time = 2  3 A’s, 5 B’s, 2 C’s, 1 D, 1 Z Third iteration (cool down time = 0)   Do the task at index 2. Array is now … 4 2 1 1 1 0 0 … Now our cool time down is 0.   Let’s move pointer index back to 0 (ie schedule the task at index 0)  Now our array looks like … 3 2 1 1 1 0 0 We have to re-sort every time our cool down time has run down
21. ### Task Scheduler (Continued) Sorting tasks We have to resort again

every time our cool down time has run down 5 3 3 0 … 0 cool down time = 1    First iteration:  4 3 3 0 <- run ﬁrst task  4 2 3 0 <- run second task
22. ### Task Scheduler (Continued) Sorting tasks We have to resort again

every time our cool down time has run down 5 3 3 0 … 0 cool down time = 1    First iteration:  4 3 3 0   4 2 3 0    Second iteration after cool down time has run down  3 2 3 0  3 1 3 0 (third task is going to get delayed and cause idle time in end) Now our third task is going to get super delayed
23. ### Task Scheduler (Continued) Final approach: 1) Store task instances in

a size 26 array. Each element in the array represents the number of instances the task needs to run
24. ### Task Scheduler (Continued) Final approach: 1) Store task instances in

a size 26 array. Each element in the array represents the number of instances the task needs to run    2) Sort the task in descending order (task with most instances in front)
25. ### Task Scheduler (Continued) Final approach: 1) Store task instances in

a size 26 array. Each element in the array represents the number of instances the task needs to run    2) Sort the task in descending order (task with most instances in front) 3) Iterate through array while cool down time is non-zero
26. ### Task Scheduler (Continued) Final approach: 1) Store task instances in

a size 26 array. Each element in the array represents the number of instances the task needs to run    2) Sort the task in descending order (task with most instances in front) 3) Iterate through array while cool down time is non-zero 4) When cool down time is over, re-sort array
27. ### Task Scheduler (Continued) Final approach: 1) Store task instances in

a size 26 array. Each element in the array represents the number of instances the task needs to run    2) Sort the task in descending order (task with most instances in front) 3) Iterate through array while cool down time is non-zero 4) When cool down time is over, re-sort array 5) We’re ﬁnished when the ﬁrst element is 0 after re-sorting
28. ### Task Scheduler (Continued) But wait! Is there an even more

efﬁcient solution?
29. ### Task Scheduler (Continued) But wait! Is there an even more

efﬁcient solution? If we can somehow just ﬁgure out how many idle slots are needed … then we can return idleSlotsNeeded + tasks

31. ### What to do when stuck? Write out test cases  sometimes

in the process of going through test  cases to get the output a general approach  will start to appear
32. ### What to do when stuck? Write out test cases  sometimes

in the process of going through test  cases to get the output a general approach  will start to appear Start with the most inefﬁcient solution you can think of that just gets the job done
33. ### Mock Interviewing Prep : Understanding the solution (20 minutes) Naive

solution is usually straight-forward
34. ### Mock Interviewing Prep : Understanding the solution (20 minutes) Naive

solution is usually straight-forward but optimal solution can be hard to understand even when the approach is presented. To fully understand it, take an input and run it through the solution to see how the solution processes the input
35. ### Mock Interviewing Try to implement solution in codepad or collabedit

ﬁrst Run solution in Leetcode to make sure it passes and is Accepted (ie : No Time Limit Exceeded) Practice communication with your interviewer
36. ### Mock Interviewing Try to implement solution in codepad or collabedit

ﬁrst Run solution in Leetcode to make sure it passes and is Accepted (ie : No Time Limit Exceeded) Practice communication with your interviewer Try to time constrain to 35 minutes a problem  still do Understanding, Matching, Prototype / Pseudocoding, Implement, Recheck, Evaluate!  Don’t be tempted to start coding too early Mentors will be popping in (me and Jing)

for us
38. ### Greedy : Summarized At every step, we do what’s best

for us How do we know we should go with an approach like this?   can the problem be broken down into small sub- problems?  can the smaller sub-problems and that their optimal solution be part of the optimal solution of the whole problem?