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.

&nbsp;
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.


&nbsp;
Constraints:


	1 &lt;= tasks.length &lt;= 105
	1 &lt;= tasks[i] &lt;= 109


class Solution:
    def minimumRounds(self, tasks: List[int]) -> int:
        dic={}
        c=0
        for i in tasks:
            if i in dic.keys():
                dic[i]+=1
            else:
                dic[i]=1
        for i in dic.keys():
            if dic[i]==1:
                return -1
            while dic[i]>=2:
                if dic[i]-3>1:
                    dic[i]-=3
                    c+=1
                else:
                    dic[i]-=2
                    c+=1
        return c
/**
	Each round, we can complete either 2 or 3 tasks of the same difficulty level
    Time: O(n)
    Space: O(n)
*/
class Solution {
    public int minimumRounds(int[] tasks) {
        int round = 0;
        Map<Integer, Integer> taskMap = new HashMap<>(); // map of <task,  number of each task>
        for (int i = 0; i < tasks.length; i++) {
            taskMap.put(tasks[i], taskMap.getOrDefault(tasks[i], 0) + 1);
        }
        
        for (Map.Entry<Integer, Integer> entry : taskMap.entrySet()) {
            if (entry.getValue() == 1) {
                return -1; // we cannot complete if there is only 1 task
            }
			// try to take as many 3's as possible
            round += entry.getValue() / 3; 
			
            /*
				We can have 1 or 2 tasks remaining. We're not supposed to take task of count 1, but we can 'borrow' 1 from the previous
				ex. [5,5,5,5,5,5,5] -> [5,5,5][5,5,5][5]
				In this example, treat the last [5,5,5], [5] as [5,5], [5,5]
            */
            if (entry.getValue() % 3 != 0) { 
                round++; 
            }
        }
        return round;
    }
}
class Solution {
public:
    int minimumRounds(vector<int>& tasks) {
        map<int,int> hm;
        for(int i=0;i<tasks.size();i++){
            hm[tasks[i]]++;
        }
        int num,freq,ans=0;
        for (auto i : hm){
            freq = i.second;
            if(freq==1)
                return -1;
            if(freq%3==0){
                ans += freq/3;
            }
            else{
                ans += freq/3 + 1;
            }
        }
        return ans;
    }
};
var minimumRounds = function(tasks) {
    const hash = {};
    let minRounds = 0;

    for (const task of tasks) {
        hash[task] = hash[task] + 1 || 1;
    }

    for (const count of Object.values(hash)) {
        if (count < 2) return -1;
        minRounds += Math.ceil(count / 3);
    }

    return minRounds;
};
Minimum Rounds to Complete All Tasks