Minimum Rounds to Complete All Tasks

Updated on 19 June, 2025
Minimum Rounds to Complete All Tasks header image

Problem Statement

In the given scenario, you are provided with an array called tasks where each element in the array signifies the difficulty level of a specific task. This array uses 0-based indexing. You have the option to tackle 2 or 3 tasks at a time, but these tasks must all have the same corresponding difficulty level. The objective is to determine the minimum number of rounds necessary to complete all the tasks provided in the array. If it's not possible to complete all tasks based on the restrictions set (i.e., complete either 2 or 3 tasks of the same difficulty each round), the function should return -1.

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.

Constraints

  • 1 <= tasks.length <= 105
  • 1 <= tasks[i] <= 109

Approach and Intuition

  1. Count Frequency of Each Task Difficulty:

    • First, we need to count how many tasks there are of each difficulty. This involves computing the frequency of each integer value in the array, which can be effectively done using a hash map.
  2. Evaluate Completing Tasks in Minimum Rounds:

    • For each unique difficulty level, calculate the minimum number of rounds needed:
      • If the count of tasks for a particular difficulty is not divisible by 2 or 3, or does not fit into combinations of twos and threes neatly (like a single leftover task when needing groups of two or three), then it would be impossible to complete those tasks. In this case, we directly return -1.
      • If the number of tasks fits exactly or can be broken down into valid groups of 2 and 3, calculate the rounds by trying different combinations of twos and threes for minimum rounds.
  3. Sum the Rounds Across All Difficulties:

    • If all difficulty levels can be tackled in valid rounds as per the rules, sum up all the rounds needed.

Illustrative Steps:

  • Begin by iterating through the frequency map of tasks, checking for each difficulty level.
  • For each level, try to break down the number of tasks into multiples of 2 and 3, looking for combinations that yield the least rounds.
  • An efficient way would be to utilize as many groups of three as possible (since it reduces the count quickly), then fill the remainder with groups of two.
  • If at any point, a difficulty level's task count cannot be divided into the permissible groups, you return -1.
  • Sum up all the calculated rounds to get the answer if all levels are successfully dividable into rounds.

This approach ensures that you compute the minimum rounds in an efficient manner, balancing between computational effectiveness and simplicity. The complexity is mainly dictated by the number of unique difficulties and ensuring each combination adheres to the constraints and conditions provided.

Solutions

  • C++
  • Java
cpp
class Solution {
public:
    int calcMinRounds(vector<int>& tasks) {
        unordered_map<int, int> taskCount;
        // Populate frequency map for each task
        for (int t : tasks) {
            taskCount[t]++;
        }
        
        int roundsRequired = 0;
        // Evaluate minimum rounds needed from task counts
        for (auto [taskID, numTasks] : taskCount) {
            // Single task can't be completed under rules
            if (numTasks == 1) {
                return -1;
            }

            if (numTasks % 3 == 0) {
                // If exactly divisible, do in triplets
                roundsRequired += numTasks / 3;
            } else {
                // Always need at least one more round for remainders after triplets
                roundsRequired += numTasks / 3 + 1;
            }
        }
        
        return roundsRequired;
    }
};

The problem "Minimum Rounds to Complete All Tasks" is formulated to determine the least number of rounds necessary to complete every task, given certain constraints on batch processing of tasks. The solution is implemented in C++. Here's a concise explanation of the approach taken to solve this problem:

  • An unordered map is used to store the frequency of each task based on the input list.
  • The main logic iterates through the map to calculate the minimum rounds required:
    • If any task appears only once, then it's impossible to complete all tasks as per the given conditions, so the function immediately returns -1.
    • For tasks that appear more than once, the number of rounds is calculated by dividing the count by 3 (the maximum allowed size of a task batch).
    • If the task count is perfectly divisible by 3, that quotient is directly added to the total round count.
    • If there are remainders, one additional round is used to cover up to two remaining tasks after forming groups of three.

This approach carefully evaluates the task list and optimizes the calculation of rounds needed to process tasks in groups as efficiently as possible, while satisfying the constraints specified.

java
class Solution {
    public int minRounds(int[] tasks) {
        Map<Integer, Integer> taskCount = new HashMap<>();
        // Frequency count of tasks
        for (int task : tasks) {
            taskCount.put(task, taskCount.getOrDefault(task, 0) + 1);
        }

        int rounds = 0;
        // Analyze the counts to calculate rounds
        for (int frequency : taskCount.values()) {
            // Impossible to complete if a task appears only once
            if (frequency == 1) {
                return -1;
            }

            if (frequency % 3 == 0) {
                // All tasks can be grouped in triplets
                rounds += frequency / 3;
            } else {
                // Need extra rounds for remainder tasks
                rounds += frequency / 3 + 1;
            }
        }

        return rounds;
    }
}

This solution is implemented in Java to determine the minimum number of rounds needed to complete all tasks given the frequency a task must be completed. Here's a breakdown of the approach:

  • Count Task Frequencies: Each task and its frequency are stored in a hashmap. This helps in keeping track of how often each task needs to be performed.

  • Calculate Minimum Rounds: The solution iterates through the frequencies of tasks:

    • Tasks with a frequency of 1: It immediately returns -1 as it's impossible to complete these tasks in the given format requiring each task be done at least twice.

    • Exact multiple of 3: If a task frequency is a direct multiple of three, the number of rounds is the quotient of the frequency divided by three.

    • Other frequencies: If not, an additional round is required for remaining tasks after grouping them into triplets as much as possible. This is calculated by frequency / 3 + 1.

  • Return Total Rounds: The sum of all calculated rounds gives the minimum rounds needed to complete all tasks.

Comments

No comments yet.