Minimum Rounds to Complete All Tasks
MediumUpdated: Aug 2, 2025
Practice on:
Problem
You are given a 0-indexed integer array tasks, where tasks[i] represents the difficulty level of a task. In each round, you can complete either 2 or 3 tasks of the same difficulty level.
Return the minimum rounds required to complete all the tasks, or -1 if it is not possible to complete all the tasks.
Examples
Example 1:
Input:
tasks = [2,2,3,3,2,4,4,4,4,4]
Output:
4
Explanation: To complete all the tasks, a possible plan is:
- In the first round, you complete 3 tasks of difficulty level 2.
- In the second round, you complete 2 tasks of difficulty level 3.
- In the third round, you complete 3 tasks of difficulty level 4.
- In the fourth round, you complete 2 tasks of difficulty level 4.
It can be shown that all the tasks cannot be completed in fewer than 4 rounds, so the answer is 4.
Example 2:
Input:
tasks = [2,3,3]
Output:
-1
Explanation: There is only 1 task of difficulty level 2, but in each round, you can only complete either 2 or 3 tasks of the same difficulty level. Hence, you cannot complete all the tasks, and the answer is -1.
Solution
Method 1 – Greedy Grouping
Intuition
The key idea is to always group tasks of the same difficulty into as many groups of 3 as possible, since 3 is more efficient than 2. If a count cannot be grouped into 2 or 3, it's impossible. For example, if there is only 1 task of a difficulty, we cannot form a valid group.
Approach
- Count the frequency of each task difficulty.
- For each frequency:
- If the count is 1, return -1 (impossible).
- Otherwise, greedily use as many groups of 3 as possible, and use groups of 2 for the remainder.
- Sum the rounds for all difficulties.
Code
C++
class Solution {
public:
int minimumRounds(vector<int>& tasks) {
unordered_map<int, int> cnt;
for (int t : tasks) cnt[t]++;
int ans = 0;
for (auto& [k, v] : cnt) {
if (v == 1) return -1;
ans += (v + 2) / 3;
}
return ans;
}
};
Go
func minimumRounds(tasks []int) int {
cnt := map[int]int{}
for _, t := range tasks {
cnt[t]++
}
ans := 0
for _, v := range cnt {
if v == 1 {
return -1
}
ans += (v + 2) / 3
}
return ans
}
Java
class Solution {
public int minimumRounds(int[] tasks) {
Map<Integer, Integer> cnt = new HashMap<>();
for (int t : tasks) cnt.put(t, cnt.getOrDefault(t, 0) + 1);
int ans = 0;
for (int v : cnt.values()) {
if (v == 1) return -1;
ans += (v + 2) / 3;
}
return ans;
}
}
Kotlin
class Solution {
fun minimumRounds(tasks: IntArray): Int {
val cnt = mutableMapOf<Int, Int>()
for (t in tasks) cnt[t] = cnt.getOrDefault(t, 0) + 1
var ans = 0
for (v in cnt.values) {
if (v == 1) return -1
ans += (v + 2) / 3
}
return ans
}
}
Python
class Solution:
def minimumRounds(self, tasks: list[int]) -> int:
cnt: dict[int, int] = {}
for t in tasks:
cnt[t] = cnt.get(t, 0) + 1
ans = 0
for v in cnt.values():
if v == 1:
return -1
ans += (v + 2) // 3
return ans
Rust
impl Solution {
pub fn minimum_rounds(tasks: Vec<i32>) -> i32 {
use std::collections::HashMap;
let mut cnt = HashMap::new();
for &t in &tasks {
*cnt.entry(t).or_insert(0) += 1;
}
let mut ans = 0;
for &v in cnt.values() {
if v == 1 {
return -1;
}
ans += (v + 2) / 3;
}
ans
}
}
Complexity
- Time:
O(n), wherenis the number of tasks. - Space:
O(m), wheremis the number of unique task difficulties.