Given a task sequence and the cool down time(k), rearrange the task sequence such that the execution time is minimal.
Solution: public static void main(String[] args) {
char[] task = findBestTaskArrangement(String.valueOf("AAABBB").toCharArray(), 2);
System.out.println(task);
System.out.println("Total time: " + computeTatalTaskTime(task, 2));
// ABABAB
// Total time:8
}
public static char[] findBestTaskArrangement(char[] tasks, int k) {
int n = tasks.length;
Map<Character, Integer> map = new HashMap<>();
for (char task : tasks) {
map.put(task, map.getOrDefault(task, 0) + 1);
}
PriorityQueue<Task> queue = new PriorityQueue<>(new Comparator<Task>() {
@Override
public int compare(Task a, Task b) {
return b.frequency - a.frequency;
}
});
for (Map.Entry<Character, Integer> entry : map.entrySet()) {
queue.offer(new Task(entry.getKey(), entry.getValue()));
}
tasks = new char[n];
int i = 0;
while (!queue.isEmpty()) {
int c = 0;
List<Task> nextRoundTask = new ArrayList<>();
while(c++ < k && !queue.isEmpty()) {
Task task = queue.poll();
task.frequency--;
// Locate the next empty slot
tasks[i++] = task.id;
if (task.frequency > 0)
nextRoundTask.add(task);
}
for (Task task : nextRoundTask) {
queue.offer(task);
}
}
return tasks;
}
// helper class
public static class Task {
char id;
int frequency;
Task(char i, int f) {
id = i;
frequency = f;
}
}
public static int computeTatalTaskTime(char[] tasks, int k) {
HashMap<Character, Integer> taskLastTimeMap = new HashMap<>();
int currTime = 0;
for (char task : tasks) {
if (taskLastTimeMap.containsKey(task)) {
int exceptedTime = taskLastTimeMap.get(task) + k + 1;
if (exceptedTime > currTime) {
currTime = exceptedTime;
} else
currTime++;
} else {
currTime++;
}
taskLastTimeMap.put(task, currTime);
}
return currTime;
}