问题描述
给你一个下标从 0 开始的整数数组
tasks
,其中tasks[i]
表示任务的难度级别。在每一轮中,你可以完成 2 个或者 3 个 相同难度级别 的任务。返回完成所有任务需要的 最少 轮数,如果无法完成所有任务,返回
-1
。
示例
示例 1:
输入:tasks = [2,2,3,3,2,4,4,4,4,4] 输出:4 解释:要想完成所有任务,一个可能的计划是: - 第一轮,完成难度级别为 2 的 3 个任务。 - 第二轮,完成难度级别为 3 的 2 个任务。 - 第三轮,完成难度级别为 4 的 3 个任务。 - 第四轮,完成难度级别为 4 的 2 个任务。 可以证明,无法在少于 4 轮的情况下完成所有任务,所以答案为 4 。示例 2:
输入:tasks = [2,3,3] 输出:-1 解释:难度级别为 2 的任务只有 1 个,但每一轮执行中,只能选择完成 2 个或者 3 个相同难度级别的任务。因此,无法完成所有任务,答案为 -1 。提示:
1 <= tasks.length <= 10^5
1 <= tasks[i] <= 10^9
问题分析:
这个题的常规做法是用贪心(看了题解才知道),那我就分享一下自己的笨作法(贪心没想出来)。我使用了一个dp数组,来计算有n个任务时需要的最少轮,同时使用一个哈希表来存储对应任务以及它出现的次数。具体见代码
代码如下:
class Solution {
public:
int minimumRounds(vector<int>& tasks) {
//如果任务总数少于2,必-1
if(tasks.size() < 2) return -1;
unordered_map<int, int> mp;
//多存三个,因为初始化需要用到前三个,ps:0,1并不需要,可以不用但不能不存
vector<int> dp(tasks.size() + 3, 0);
dp[2] = 1;
dp[3] = 1;
dp[4] = 2;
//O(n)组建dp数组
for(int i = 5; i < dp.size(); ++i){
dp[i] = min(dp[i - 2] + 1, dp[i - 3] + 1);
}
for(int i = 0; i < tasks.size(); ++i){
mp[tasks[i]] ++;
}
int res = 0;
//遍历哈希,如果有一个元素少于2,return -1,否则加对应次数的dp
for(auto &[x, v] : mp){
if(v < 2) return -1;
res += dp[v];
}
return res;
}
};