力扣 621. 任務排程器
題目描述
給你一個用字元陣列 tasks
表示的 CPU
需要執行的任務列表。其中每個字母表示一種不同種類的任務。任務可以以任意順序執行,並且每個任務都可以在 1
個單位時間內執行完。在任何一個單位時間,CPU
可以完成一個任務,或者處於待命狀態。
然而,兩個相同種類的任務之間必須有長度為整數 n
的冷卻時間,因此至少有連續 n
個單位時間內 CPU
在執行不同的任務,或者在待命狀態。
你需要計算完成所有任務所需要的最短時間。
示例 1:
輸入:tasks = ["A","A","A","B","B","B"], n = 2
輸出:8
解釋:A -> B -> (待命) -> A -> B -> (待命) -> A -> B
在本示例中,兩個相同型別任務之間必須間隔長度為 n = 2 的冷卻時間,而執行一個任務只需要一個單位時間,所以中間出現了(待命)狀態。
示例 2:
輸入:tasks = ["A","A","A","B","B","B"], n = 0
輸出:6
解釋:在這種情況下,任何大小為 6 的排列都可以滿足要求,因為 n = 0
["A","A","A","B","B","B"]
["A","B","A","B","A","B"]
["B","B","B","A","A","A"]
...
諸如此類
示例 3:
輸入:tasks = ["A","A","A","A","A","A","B","C","D","E","F","G"], n = 2
輸出:16
解釋:一種可能的解決方案是:
A -> B -> C -> A -> D -> E -> A -> F -> G -> A -> (待命) -> (待命) -> A -> (待命) -> (待命) -> A
提示:
1 <= task.length <= 104
tasks[i]
是大寫英文字母n
的取值範圍為[0, 100]
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/task-scheduler
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
桶思想圖解
現在假設:
- 冷卻時間
n = 2
- 任務列表
tasks = [A, A, A, B, B, B, C]
構造一個寬度為 n + 1
的桶,可以往其中放置 3
個任務。由題意知,n + 1
的桶寬度恰好滿足這樣的條件:
- 只要同一個桶不出現相同的任務,就能夠滿足相同任務間隔至少為
n
的冷卻條件。
我們恰好需要 h
個這樣的桶,h
為 tasks
任務列表中的最大任務數,也就是 3
。因為 A
和 B
都出現了 3
次,如果桶個數小於 3
,會導致同一個桶中出現相同任務,不滿足冷卻條件;當然也不能大於 3
,因為我們要求的是最小任務耗時。
從上到下把任務放置到桶的空位中,得到下圖:
最後一個桶沒有填滿,所以此時完成任務的總時間為:
(h - 1) * (n + 1) + w
w
為最後一個桶的實際佔用寬度,可以通過計算一共有幾種任務達到了最大任務數h
得出。本例中,A
和B
都達到了最大任務數,所以w == 2
。- 代入計算,最後答案為
8
執行任務時按照從左往右,從上往下的順序,得出來執行任務序列為:
[A, B, C, A, B, 冷卻, A, B]
現在考慮任務非常多的情況:
- 冷卻時間還是為
n = 2
- 任務列表增加了一些任務
tasks = [A, A, A, B, B, B, C, C, D, D, E, F, G]
在之前的基礎上,只要再填入任務 C
和 D
,桶就滿了,剩下的往哪裡放?
此時可以依次為三個桶擴容,每次擴容一格,如果不夠繼續追加,填入剩下的任務:
這下所有任務都安排上了!由於剩下的相同任務數必定小於桶的總高度 h
,所以在同一個桶中(也就是同一行中)不會出現相同的任務,這樣也就保證了冷卻時間的條件。
對於這種任務排布,完成任務的總時間恰好等於任務數:
len(tasks)
執行任務時,仍然按照從左往右,從上往下的順序,得出來執行任務序列為:
[A, B, C, D, G, A, B, C, E, A, B, D, F]
最終的答案需要在兩種情況之間取最大值:
max(len(tasks), (h - 1) * (n + 1) + w)
一行解:桶思想
藉助海象運算子寫出來的一行解。
class Solution:
def leastInterval(self, tasks: List[str], n: int) -> int:
return max(len(tasks), ((h := (c := Counter(tasks)).most_common(1)[0][1]) - 1) * (n + 1) + [*c.values()].count(h))
執行結果:
執行結果:通過
執行用時:56 ms, 在所有 Python3 提交中擊敗了95.04% 的使用者
記憶體消耗:13.8 MB, 在所有 Python3 提交中擊敗了7.04% 的使用者
不過還是來看看四行的正常寫法吧:
class Solution:
def leastInterval(self, tasks: List[str], n: int) -> int:
c = Counter(tasks)
h = c.most_common(1)[0][1]
w = [*c.values()].count(h)
return max(len(tasks), (h - 1) * (n + 1) + w)
簡單說明:
- 使用
collections.Counter
對tasks
進行計數,鍵為大寫字母,值為出現頻次。 h
是桶的個數,為tasks
任務列表中的最大任務數。w
是最後一個桶的實際佔用寬度,為最後一行任務個數,通過計算一共有幾種任務達到了最大任務數得出。
2020.12.05
相關文章
- 力扣-621. 任務排程器力扣
- 621. 任務排程器 (構造)
- 【LeetCode】每日一題621. 任務排程器LeetCode每日一題
- LeetCode每日一題--621. 任務排程器(雜湊表)LeetCode每日一題
- LeetCode 621 任務排程器LeetCode
- 任務排程
- Airflow 任務排程AI
- Laravel 任務排程Laravel
- 分散式任務排程分散式
- Spring 指南(排程任務)Spring
- Spark中資源排程和任務排程Spark
- Timer和TimerTask 任務排程
- 聊聊PowerJob的任務排程
- Linux 定時任務排程Linux
- 分散式排程任務-ElasticJob分散式AST
- laravel框架任務排程(定時執行任務)Laravel框架
- 比特幣原始碼分析:任務排程器的使用比特幣原始碼
- Windows 10任務排程器曝出新零日漏洞Windows
- Python任務排程模組APSchedulerPython
- LTS分散式任務排程部署分散式
- 用海豚排程器定時排程從Kafka到HDFS的kettle任務指令碼Kafka指令碼
- 深入 Java Timer 定時任務排程器實現原理Java
- 使用寶塔計劃任務啟動laravel排程器Laravel
- LiteOS-任務篇-原始碼分析-任務排程函式原始碼函式
- Spring排程定時任務的方式Spring
- Android 中的定時任務排程Android
- 任務排程的思考和總結
- Flink - Task 任務排程執行流程
- 任務排程框架Quartz快速入門!框架quartz
- iOS 任務排程器:為 CPU 和記憶體減負iOS記憶體
- Linux 中 Laravel 任務排程不執行LinuxLaravel
- 真香!SpringBoot官方支援任務排程框架了!Spring Boot框架
- Aloha:一個分散式任務排程框架分散式框架
- 中介軟體---分散式任務排程---Celery分散式
- 任務排程的並行演算法並行演算法
- 使用Java實現定時任務排程Java
- xxl-job,任務排程中心快速上手
- 詳解 MySQL 用事件排程器 Event Scheduler 建立定時任務MySql事件