方法一:贪心算法
解题思路:
使用贪心的思想,先把出现最多的任务分配了(即每隔n个单位时间分配一个任务),然后再把其它任务填上。如下图
所以需要先计算各任务出现的次数,找到出现最多的任务,程序中使用map来计数,然后复制到vector,再通过自定义的比较函数cmp,对vector进行排序。
结果的计算公式为:(x - 1) * (n + 1) + num
其中,x表示出现次数最多的任务的次数,n表示输入参数中的时间间隔,num表示出现次数为 x 的任务总数。
有一种特殊情况需要考虑,那就是:num的值要大于 n 的时候,例子如下:
输入:["A", "A","A","B","B","B","C","C","C","D","D","D"], n = 2
按照公式(x - 1) * (n + 1) + num,结果为 2 * 3 + 4 = 10,比tasks的size 12 还小,显然不对。这种时候,就应该返回tasks的size大小。
class Solution {
public:
//自定义比较函数,必须在前面加上 static,不然会报错
static bool cmp(const pair &v1, const pair &v2){
return v1.second > v2.second;
}
int leastInterval(vector& tasks, int n) {
map mp;
//先将tasks中任务计数在map中
for(int i = 0; i < tasks.size(); i++){
map::iterator it;
it = mp.find(tasks[i]);
if(it == mp.end()) mp[tasks[i]] = 1;
else mp[tasks[i]]++;
}
//将map中的元素转到vector中,之后再进行sort排序,找到出现次数最多的任务
vector > count;
for(map::iterator iter = mp.begin(); iter != mp.end(); iter++){
count.push_back(make_pair(iter->first, iter->second));
}
sort(count.begin(), count.end(), cmp);
int num = 0; //用于记录出现次数最多的任务有多少个
for(int i = 0; i < count.size(); i++){
if(count[i].second == count[0].second) num++;
else break;
}
//出现次数最多的任务为count[0].first, 其出现次数是count[0].second
int res = (count[0].second - 1) * (n + 1) + num;
if(res < tasks.size()) return tasks.size();
else return res;
}
};
其实,更简单的方法可以直接就不需要map,只用一个包含26个元素(对应26个字母)的vector计数,就能解答这道题目。