題目描述
給定一個char數組,代表CPU需要做的任務,包含A-Z,不用考慮順序,每個任務能在1個單位完成。但是有規定一個非負整數n代表兩個相同任務之間需要至少n個時間單位。球最少數量的時間單位完成所有任務。
思路
先要找到最大的任務個數x,若總任務類數>=n,則時間至少為(x-1)*(n+1)+最大值類數;但是對於特殊情況:4A3B3C3D,n=2,則使用原來的思路(先放最多類的,再按照類別從前往后填空) 不能獲得最小值。所以沒有做出來。
Solution
總結了一下,LeetCode上的達人們的思路主要有這樣幾種:
- 先統計詞頻,再排序,從后往前找到第一個不是最大詞頻的下標i,結果是tasks.length或(c[25] - 1) * (n + 1) + 25 – i中大的那一個,25-i就是最大詞頻的任務類,這個和我的思路是一樣的。證明:最大詞頻是k,則創建k個塊,每一塊開頭是最大詞頻的任務構成的(輸入AACCCDDEEE,則開頭是CE),詞頻由大到小插入每一塊。97.69%,10ms。
- 貪心,利用優先隊列排序:隊列中保存<類型,個數>的map,並且按照個數由大到小排序。按照詞頻由大到小取出n+1個或者隊列中全部(若沒有取出全部,則總長度要加上空閑個數),再把詞頻-1之后不為0的放回隊列中。直到隊列空了為止。——其實也和前面相同,總是選擇詞頻最大的填入每一塊。
- 使用操作系統的思想,在時間為time的時候,把time-1-n凍結的任務放回等待隊列waitingQueue,在一個循環結束的時候,如果還有這一類task待完成,放到tasksTable。具體做法:先用HashMap統計詞頻,再用優先隊列waitingQueue排序,聲明一個冷卻HashMap表coolDownTable,當隊列不空或者冷卻表不空的時候,找到冷卻表time-n-1對應的任務char,拿出放到等待隊列中,如果等待隊列不空{拿出任務,剩余任務個數-1並放到tasksTable,如果剩余任務個數不為0放到coolDownTable.put(time, task); } time++。返回time
- 類似上面,模擬的思想:對於m個任務,先是每類任務的冷卻時間-1,然后找到詞頻最大的任務及其下標,如果它的詞頻>-1,則取這個任務(詞頻-1,處理++,冷卻時間+n);否則(所有任務詞頻都為-1),空閑+1.返回處理+空閑時間
代碼
只是實現了第一個solution的代碼:
public int leastInterval(char[] tasks, int n) {
int[] freq=new int[26];
int maxFreq=0,maxFreqCount=0;
for(int i=0;i<tasks.length;i++){
freq[tasks[i]-'A']++;
}
for(int i=0;i<26;i++){
if(freq[i]>maxFreq){
maxFreq=freq[i];
maxFreqCount=1;
}else if(freq[i]==maxFreq){
maxFreqCount++;
}
}
return Math.max(tasks.length,(maxFreq-1)*(n+1)+maxFreqCount);
}