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





思路

自己的思路:首先用哈希表统计出每个任务的数量,若有任务数量为1说明无法完成。对于其他的任务,通过找规律:

  • 任务量为2:1轮完成
  • 任务量为3:1轮完成
  • 任务量为4:2轮完成
  • 任务量为5:2轮完成
  • 任务量为6:2轮完成
  • 任务量为7:3轮完成
  • 任务量为8:3轮完成
  • 任务量为9:3轮完成
  • 任务量为10:4轮完成
  • 任务量为11:4轮完成
    ......

可见任务量为$c$,则需$\lceil \frac{c}{3} \rceil$次完成。根据这个规律,循环遍历即可。

关于这个规律,灵山大佬给出了详细的证明。

代码

自己的代码:

class Solution:
   def minimumRounds(self, tasks: List[int]) -> int:
       num_dict = {}
       n = len(tasks)
       for i in range(n):
           if tasks[i] in num_dict:
               num_dict[tasks[i]] += 1
           else:
               num_dict[tasks[i]] = 1

       
       ans = 0
       for v in num_dict.values():
           if v == 1:
               return -1
           else:
               ans += ceil(v/3)
       
       return ans
       

以上是自己的代码,相比之下灵神的思路跟自己一样,但是代码优雅了太多:

class Solution:
    def minimumRounds(self, tasks: List[int]) -> int:
        cnt = Counter(tasks)
        if 1 in cnt.values():
            return -1
        return sum((c + 2) // 3 for c in cnt.values())

且不说一些函数调用的技巧,灵神在向上取整这里更进了一步:

$$ \lceil \frac{c}{3} \rceil = \lfloor \frac{c+2}{3} \rfloor $$

将向上取整改进为了向下取整,因此可以用python的//运算,效率比ceil()高得多。

总结

  1. python封装了统计列表词频的函数:Counter(),传入值是一个列表,输出是一个字典,统计key的出现次数。
  2. 字典遍历:

    • 遍历Key:for k in dict.keys():
    • 遍历Value:for v in dict.values()
    • 同时遍历Key和Value:for k, v in dict.items()

声明:奋斗小刘|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - LeetCode 2244 完成所有任务需要的最少轮数


Make Everyday Count