完成所有任务需要的最少轮数

标签: 贪心 数组 哈希表 计数

难度: Medium

给你一个下标从 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 <= 105
  • 1 <= tasks[i] <= 109

Submission

运行时间: 81 ms

内存: 30.9 MB

class Solution:
    def minimumRounds(self, tasks: List[int]) -> int:
        cnt = Counter(tasks)

        ans = 0
        for c in cnt.values():
            if c == 1:
                return -1
            else:
                ans += (c+2)//3
        return ans

Explain

该题解首先使用计数器统计每个任务难度出现的次数。然后遍历这些计数,针对每个计数,判断是否为1,因为一个任务无法在一个轮次内完成(要求每轮完成2或3个相同任务)。如果某个任务的数量为1,则直接返回-1,表示无法完成所有任务。否则,计算完成这种难度任务所需的最少轮数,利用数学技巧(c+2)//3得到向上取整的结果,即在每轮尽可能完成3个任务,然后计算总轮数。最后,返回所有任务所需的总轮数。

时间复杂度: O(n)

空间复杂度: O(n)

class Solution:
    def minimumRounds(self, tasks: List[int]) -> int:
        cnt = Counter(tasks)  # 计数每种难度的任务数量

        ans = 0  # 初始化完成所有任务所需的最少轮数
        for c in cnt.values():  # 遍历每种任务的数量
            if c == 1:
                return -1  # 如果某个任务的数量为1,返回-1,因为无法完成
            else:
                ans += (c+2)//3  # 计算完成这种任务所需的轮数,向上取整
        return ans  # 返回总轮数

Explore

在算法中,当任务数量正好为2时,直接计算为1轮。这是因为题目规定每轮可以完成2或3个相同的任务。因此,如果任务数量正好为2,可以在一轮中完成这两个任务,无需特别的处理方式。

这个公式`(c+2)//3`是一种向上取整的计算方法,用于计算至少需要多少轮可以完成`c`个任务。当`c % 3 == 0`时,正好每轮完成3个任务;`c % 3 == 1`时,会有一轮只能完成一个任务,这不符合题目要求,因此通过添加2个假想的任务,使其能被3整除,从而计算轮数;`c % 3 == 2`时,正好有一轮完成2个任务。这种计算方式确保了不管任务数如何,都能通过尽可能多地每轮完成3个任务来最小化轮数,而添加的2只是为了使整除3时计算方便,并不会影响实际轮数的计算。

在这个题解中,我们使用的`(c+2)//3`公式已经考虑了最优的组合方式。对于5个任务的例子,按照公式计算为`(5+2)//3 = 7//3 = 2`轮,这符合3个任务一轮和2个任务一轮的最优组合(3+2)。因此,该公式已经自然地考虑了不同的组合方式,以确保总轮数是最小的。

题解中每种难度的任务是独立处理的,没有考虑不同难度任务之间的依赖或相互影响。因为每轮只能完成相同难度的任务,所以不同难度的任务无法在一轮中组合。每种难度的任务都按其数量单独计算所需的最少轮数,然后将这些轮数相加得到完成所有任务的总轮数。这保证了计算的简洁性和正确性。