*621J. Task Scheduler
Method 1 Best O(N) O(1);
对问题的观察: 为什么CPU会闲置,就是因为相同的任务的出现。如果就是 ABCDE,那么时间就是tasks长度。 假如一个任务 AAA...A,k个A, 冷却时间 n = 2, 那么就得至少 (k - 1) (n + 1) + 1。 因为前 k - 1 个占用 (k - 1) (n + 1) 时长,然后得 + 1. 如果有一大串任务 AAABBBCCCDDDEEEFFF.... , 首先我们知道,时间至少是 tasks 长度的。 其次时间取决于 (k - 1) (n + 1) 这个大框架能容下多少。 如果这个大框架有空闲的,说明剩下的不足以填满,那么答案就是 (k - 1) (n + 1) + p. p 是 k 次的任务数量。比如 k 个 A 和 k 个 B, p = 2. 反之,如果它填满了。那么一定是 tasks 的长度是答案,这个确实很有意思,不知道怎么证明。
class Solution {
public int leastInterval(char[] tasks, int n) {
int[] counts = new int[26];
int maxCount = 0;
int numberOfMax = 1;
for(char c : tasks) {
counts[c - 'A'] ++;
if( counts[ c - 'A'] > maxCount ) {
maxCount = counts[ c - 'A'];
numberOfMax = 1;
}else if ( counts[ c - 'A'] == maxCount ){
numberOfMax++;
}
}
return Math.max( tasks.length, (maxCount - 1)*(n + 1) + numberOfMax);
}
}
Mathod 2 Not best
class Solution {
public int leastInterval(char[] tasks, int n) {
//初始化一个 max heap
PriorityQueue<Integer> heap = new PriorityQueue<Integer>((n1, n2) -> n2 - n1);
int[] map = new int[26]; // 26 字母, 更多的用 hashmap
for(char c : tasks){
map[c - 'A']++;
}
for(int f: map){// f for frequency
if( f > 0){
heap.add(f);
}
}
// 记录 time interval
int time = 0;
while(!heap.isEmpty()){
int i = 0;// 记
//顺序做任务,做n个就取出。
List<Integer> temp = new ArrayList<>();
//当不超过n个任务时
while(i <= n){
//如果有任务待做
if(!heap.isEmpty()){
if( heap.peek() > 1 ){
//任务数量减1
temp.add(heap.poll() - 1);
}else{
//取出已经做完的任务
heap.poll();
}
}
//不管做没做任务,idle也要时间++
time++;
//如果队列都空了,并且temp的也做完了,直接结束 可以返回了
if(heap.isEmpty() && temp.size() == 0){
return time;
}
//子时间指针++
i++;
}
//把任务加回去。
for(int l: temp){
heap.add(l);
}
}
return time;
}
}
Last updated
Was this helpful?