leetcode 621 Task Scheduler
題目描述
Given a char array representing tasks CPU need to do. It contains capital letters A to Z where different letters represent different tasks.Tasks could be done without original order. Each task could be done in one interval. For each interval, CPU could finish one task or just be idle.
However, there is a non-negative cooling interval n that means between two same tasks, there must be at least n intervals that CPU are doing different tasks or just be idle.
You need to return the least number of intervals the CPU will take to finish all the given tasks.
Example 1:
Input: tasks = [‘A’,’A’,’A’,’B’,’B’,’B’], n = 2
Output: 8
Explanation: A -> B -> idle -> A -> B -> idle -> A -> B.
Note:
The number of tasks is in the range [1, 10000].
The integer n is in the range [0, 100].
思路分析
本題是leetcode contest 37新鮮出爐的一道題目,客觀來講,本題不算太難,但是題解的思路還是有助於我們理解這一類題目的一些解決方式,給類似的題目提供思考方向,因此有整理的必要。
直譯本題就是任務規劃,題目的核心意思是,安排一堆任務,這些任務由一個task陣列給出,相同任務之間,最少有n的執行時間間隔,在n的執行時間間隔內,可以執行執行別的任務或者處於就緒狀態。最終的目標是安排所有的task,使總的執行時間最小。
對於兩個相同的task,我們假設都為A,兩者之間的最小間隔是n,這就是題目想表達的含義,我們首先考慮出現頻率最高的task,我們仍假設為A,出現的頻率為x,我們知道,要滿足A的時間需求,我們至少應該有 x-1個n的間隔。對於頻率小於x的任務,假設為B,我們按序插入任務B,可以發現,這樣的插入也是滿足要求的。滿足A的最小安排,最終所有的任務安排都是滿足要求的(先不考慮任務多得插不進去的情況)。
因為出現頻率最高的元素可能不止一個,我們假設為k個,那麼這種情況下最終的時間需求為:
(x-1)*n+k
若出現完全插滿的情況,上式仍然成立,但顯然,多餘的task沒有計算。這時候我們觀察形成的序列,如果完全插滿,這時候的時間需求顯然就是整個陣列的大小了。
根據上述的分析,寫出的程式碼如下:
class Solution {
public:
int leastInterval(vector<char>& tasks, int n) {
// frame size
vector<int> mVec(26,0);
for(auto &val:tasks) {
mVec[val-'A']++;
}
sort(mVec.begin(),mVec.end());
int i = 25;
while(i>=0&&mVec[25]==mVec[i])i--;
return max((mVec[25]-1)*(n+1)+25-i,static_cast<int>(tasks.size()));
}
};