Posts Task Scheduler
Post
Cancel

Task Scheduler

Problem Description

Given a characters array tasks, representing the tasks a CPU needs to do, where each letter represents a different task. Tasks could be done in any order. Each task is done in one unit of time. For each unit of time, the CPU could complete either one task or just be idle.

However, there is a non-negative integer n that represents the cooldown period between two same tasks (the same letter in the array), that is that there must be at least n units of time between any two same tasks.

Return the least number of units of times that the CPU will take to finish all the given tasks.

leetcode

Solution

Explanation

snapshot

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Solution {

    public int leastInterval(char[] tasks, int n) {

        Map<Character, Integer> frequency = new HashMap<>();

        //get max frequency
        int maxFrequency = -1;

        for(int i=0; i<tasks.length; i++){

            Character c = tasks[i];

            if(frequency.containsKey(c)){
                frequency.put(c, frequency.get(c)+1);
            }else{
                frequency.put(c, 1);
            }
            maxFrequency = Math.max(maxFrequency, frequency.get(c));
        }

        int lastRowLength = 0;

        for(java.util.Map.Entry entry: frequency.entrySet()){
            int v = (int) entry.getValue();
            if(v == maxFrequency) lastRowLength++;
        }

        int numberOfRows = maxFrequency;
        int columns = n+1;

        return Math.max((((numberOfRows-1)*columns)+lastRowLength), tasks.length);

    }

}

Using Max Heap & Queue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
class Solution {

    public int leastInterval(char[] tasks, int n) {

        PriorityQueue<Integer> heap = new PriorityQueue<>(Collections.reverseOrder());

        Map<Character, Integer> frequency = new HashMap<>();
        for(int i=0; i<tasks.length; i++){
            Character c = tasks[i];
            if(frequency.containsKey(c)){
                frequency.put(c, frequency.get(c)+1);
            }else{
                frequency.put(c, 1);
            }
        }

        //insert the frequencies to max heap
        for(java.util.Map.Entry e: frequency.entrySet()){
            heap.add((int)e.getValue());
        }
        
        //to keep a track of when this task can be executed next time
        Queue<Pair> queue = new LinkedList<>();

        //current time starts from 0
        int time = 0;

        //while the heap and queue are not empty
        while(!heap.isEmpty() || queue.size() > 0){
            
            //pick up the highest frequency element
            if(!heap.isEmpty()){

                //get its frequency
                int f = heap.poll();
                
                //if the frequency is 1, we don't need to execute it again in the future obviously
                //but it it's more than 1, put that to the queue and set the nextTime as (currentTime + minIdleRequired which is n)
                if(f > 1)
                    queue.add(new Pair(f-1, time+n));

            }
            
            //While there are tasks in the queue which can now be executed, put them back to the heap
            while(!queue.isEmpty() && queue.peek().nextTime <= time){
                heap.add(queue.poll().frequency);
            }

            //increase current time by 1
            time++;
            
        }

        return time;

    }
}

class Pair{

    int frequency;
    int nextTime;

    Pair(int f, int t){
        this.frequency = f;
        this.nextTime = t;
    }
}
This post is licensed under CC BY 4.0 by the author.