這道題主要是找規律,優化的時候能夠採用貪心算法的思想。
<!-- more -->java
給定一個用字符數組表示的 CPU 須要執行的任務列表。其中包含使用大寫的 A - Z 字母表示的26 種不一樣種類的任務。任務能夠以任意順序執行,而且每一個任務均可以在 1 個單位時間內執行完。CPU 在任何一個單位時間內均可以執行一個任務,或者在待命狀態。git
然而,兩個相同種類
的任務之間必須有長度爲 n 的冷卻時間,所以至少有連續 n 個單位時間內 CPU 在執行不一樣的任務,或者在待命狀態。github
你須要計算完成全部任務所須要的最短期
。算法
示例 1:segmentfault
輸入: tasks = ["A","A","A","B","B","B"], n = 2 輸出: 8 執行順序: A -> B -> (待命) -> A -> B -> (待命) -> A -> B.
注:數組
原題url:https://leetcode-cn.com/probl...優化
這道題的思路,正向推導的話,其實就是優先排出現次數多的任務,根據間隔 n ,填充任務,直到全部任務的次數最終都減爲0。url
所以,咱們能夠用數組存儲任務的總次數(由於用大寫英文字母表示任務,那就表明最多隻能有26種任務),排序以後,按照間隔 n ,從大到小取任務,取完後,再對數組排序,重複上述取任務的過程,直到數組的最大值爲0。spa
接下來咱們看看代碼:code
public class Solution { public int leastInterval(char[] tasks, int n) { // 將task放入數組中 int[] countArray = new int[26]; for (char task: tasks) { countArray[task - 'A']++; } // 從小到大,進行排序 Arrays.sort(countArray); // 最終耗時 int time = 0; // 從大到小開始遍歷 while (countArray[25] > 0) { // 每次遍歷前n個數 int i = 0; while (i <= n) { // 說明全部任務已經執行完成 if (countArray[25] == 0) { break; } // 遍歷 if (i < 26 && countArray[25 - i] > 0) { countArray[25 - i]--; } // 耗時+1 time++; // 更換任務 i++; } // 從小到大排序 Arrays.sort(countArray); } return time; } }
提交OK,但執行時間上確實不太好,只戰勝了47.62%
的 java 執行時間,其時間複雜度爲O(time)
, time 表明最終的執行時間。
咱們再來想一想這道題,影響最終執行時間的,有兩個因素,一個是任務中出現的最大次數,另外一個就是間隔 n 了。
若是咱們站在最多任務的角度,來看這個問題,假設其最大次數爲 maxCount,那麼該任務所需的最短執行時間爲(maxCount - 1) * (n + 1) + 1
,若是還有其餘 i 個和 maxCount 相同次數的任務,那麼須要在最終的結果上再加上 i。
那麼上面求出來的就是正確答案了嗎?
並非,由於上面的最短期,是當剩餘時間片可以塞滿任務數小於 maxCount 的全部任務。假設 n 很小,那麼剩餘任務確定須要在任務數等於 maxCount 的那些任務執行完以後,還要繼續執行。
但由於最大任務已經能夠知足在間隔時間內執行完,那麼出現次數小於 maxCount 的任務,確定能夠連續執行完成的,也就是不須要空閒等待時間。那麼此時的最短執行時間也就是總任務數了。
接下來咱們看看代碼:
public class Solution { public int leastInterval(char[] tasks, int n) { if (tasks.length == 0 || n == 0) { return tasks.length; } // 將task放入數組中 int[] countArray = new int[26]; for (char task : tasks) { countArray[task - 'A']++; } // 從小到大,進行排序 Arrays.sort(countArray); // 獲取最大次數 int maxCount = countArray[25]; // 若是其餘次數都比maxCount小的話,求出針對maxCount的最短期 int result = (maxCount - 1) * (n + 1); // 遍歷countArray for (int i = 25; i >= 0; i--) { // 若是有和maxCount相同的,則執行時間+1 if (countArray[i] == maxCount) { result++; } // 不然,直接結束 else { break; } } // 若是總任務數比理論上的最短期長,說明任務不少,但能夠把每一個桶填滿,所以最短期也就是總任務數 return Math.max(result, tasks.length); } }
提交OK ,在全部 Java 提交中擊敗了100.00%
的用戶,確實快了不少。其時間複雜度爲O(M)
,M 表明總任務數。
以上就是這道題目個人解答過程了,不知道你們是否理解了。這道題主要是找規律,優化的時候能夠採用貪心算法的思想。
有興趣的話能夠訪問個人博客或者關注個人公衆號、頭條號,說不定會有意外的驚喜。
公衆號:健程之道