621. Task Scheduler - Medium
前往題目
之前寫的文章
有難度的一題
思路
很重要的觀念是task
的頻率由大到小,每次取前n
個來排,也就是說假設今天是n=2
,然後有A
出現5
次,B
出現3
次,C
出現1
次,那就是取AB
,然後A
和B
各減1
。這樣可以保證最少次數的Idle
,不然先把小頻率的都取完了,之後為了滿足條件就必須每次都放n — 1
個Idle
,就不是最小單位時間了
priority queue(pq)
來儲存每個task
的頻率,由大到小- 在
pq
裡,取n
或是pq.size()
當作k
,看誰比較小,因為取到比較大的那個,會導致pq
沒有item
或是取超出n
個item
- 取出
k
個之後,每個任務頻率做相應的減去 - 如果還不是最後一輪,就加上
n
個,因為每個區間要n
個;如果是最後一輪,加上k
,因為不需要再Idle
了 - 還有
task
的話再塞回去pq
裡面進行下一輪的安排
Code
class Solution {
public int leastInterval(char[] tasks, int n) {
Map<Character, Integer> map = new HashMap();
// 儲存任務與任務次數
for (char task : tasks) {
map.put(task, map.getOrDefault(task, 0) + 1);
}
// 頻率由高到低
PriorityQueue<Integer> pq = new PriorityQueue<Integer>(Collections.reverseOrder());
for (Map.Entry<Character, Integer> a: map.entrySet()) {
pq.add(a.getValue());
}
// A series of n different tasks
++n;
int res = 0;
while (!pq.isEmpty()) {
// In case k is larger than tasks
int k = Math.min(n, pq.size());
List<Integer> temp = new ArrayList<>();
// Schedule k tasks
for (int i = 0; i < k; ++i) {
int f = pq.poll();
--f;
if (f != 0)
// Add to temp for next round if the task still exist
temp.add(f);
}
// Still has more tasks
if (!temp.isEmpty()) {
res += n;
} else {
// Last round, add the rest, no need idle
res += k;
}
// Add updated frequencies
for (int i : temp) {
pq.offer(i);
}
}
return res;
}
}
621. Task Scheduler - Medium
https://f88083.github.io/2024/04/10/621-Task-Scheduler-Medium/