Question: Our CPU needs to take care of a list of tasks and some of the tasks they are same. This perticular CPU doesn't allow two same tasks to be processed within n units. The question is asking for how many units at least for this CPU to handle these tasks. We know the total number of tasks the CPU needs to take care of so the key to this question is how many idles we need to add.
First, let's look at the most general case: we have a list of tasks and we have only one top freqency, and the rest number of tasks will not over the number of idles we have.
For example, A-3, B-2 and n=2
A _ _ A _ _ A We have 4 idles and we have two more tasks to handle. They could just fill out the positions where the idles are.
So the number of idles is 2*2
If we generalize this, the number of idles = (the top frequency - 1)*n
The second case is that if the number of rest tasks is over the number of idles.
For example, A-3, B-2, C-2, D-2 and n=2
A _ _ A _ _ A We have 4 idles at the very beginning and we have 6 more tasks to handle. If we fill like this, A B C A B C A. Why do we put the D's? We could just put like this A B C D A B C D A and this will not violate the rule we set for this CPU.
If we generalize this, the number of extra units we add except the top frequency = max((the top frequency - 1)*n, the rest num of tasks)
The third case is that if we have multiple top frequencies.
For example, A-3, B-3, C-1 and n=2
This will only change how we calculate the numebr of idles if we look at A and B as a whole.
A B _ A B _ A B So we have two idles and one more task to handle.
If we generalize this, the number of ideles = (the top frquency - 1) * (n - the number of top frequencies)
So the final equation will be
the number of extra units we add except the top fequencies = max((the top frequency -1 )*(n - the number of top frequencies), the rest num of tasks)
This could also handle the case if the number of top frequencies is over n.
def leastInterval(self, tasks: List[str], n: int) -> int:
maxFreq = 0
countMax = 0
status = {}
for t in tasks:
status[t] = status.get(t, 0) + 1
if status[t]>maxFreq:
countMax = 1
maxFreq = status[t]
elif status[t]==maxFreq:
countMax += 1
numOfIdles = (maxFreq-1)*(n-(countMax-1))
res = maxFreq*countMax + max(numOfIdles, len(tasks)-maxFreq*countMax)
return res
class Solution {
public:
int leastInterval(vector<char>& tasks, int n) {
if(tasks.empty()) return 0;
vector<int> count(26,0);
for(char task:tasks){
count[task-'A']++;
}
sort(count.begin(), count.end(), greater<>());
int pre = count[0]-1;
int res = (n+1)*pre;
int temp = res;
int i;
for(i=0;count[i]==count[0];i++){
res++;
temp -=pre;
}
int cnt =0;
for(;count[i]!=0;i++){
temp -= count[i];
}
if(temp<0)
res += -temp;
return res;
}
};