【算法题】最多能工作多少周?—《按规则完成项目阶段任务》题解
题目描述
给你 n
个项目,编号从 0 到 n - 1
。同时给你一个整数数组 milestones
,其中每个 milestones[i]
表示第 i
个项目中的阶段任务数量。
你每周可以完成一个项目中的恰好一个阶段任务,且每周都必须工作。但是,有以下限制:
- 连续两周不能完成同一个项目的任务。
- 一旦所有项目的所有任务完成,或者执行剩下的任务会导致规则被违反,你就停止工作。
求你最多能工作多少周。
示例
示例 1:
输入:milestones = [1,2,3]
输出:6
一种可能的工作安排:
第1周:完成项目0的任务
第2周:完成项目2的任务
第3周:完成项目1的任务
第4周:完成项目2的任务
第5周:完成项目1的任务
第6周:完成项目2的任务
总共工作6周。
示例 2:
输入:milestones = [5,2,1]
输出:7
可能的工作安排:
第1周:项目0
第2周:项目1
第3周:项目0
第4周:项目1
第5周:项目0
第6周:项目2
第7周:项目0
第8周不能执行,因为连续两周会做项目0任务,违反规则。
解题分析
这道题的核心是 如何在「不能连续两周完成同一个项目任务」的规则限制下,最大化完成任务的周数。
直觉
- 如果所有项目的任务数比较均衡,比如
[1, 2, 3]
,你可以交替完成不同项目的任务,直到完成所有任务,最大周数就是任务总数之和。 - 但如果某一个项目任务数远远多于其他项目,比如
[10, 2]
,就会出现「任务太集中导致无法连续交替完成」的问题。
关键点
我们关注两个指标:
max_m
= 最大任务数(任务最多的项目)rest
= 其余项目任务数的总和
总任务数为 total = sum(milestones)
。
规则推导
- 如果最大任务数
max_m
小于或等于其他项目任务数之和加 1,即
max_m <= rest + 1
则说明任务比较均衡,可以保证交替完成任务,不会因为同一项目任务太多而被卡住。
此时,可以完成所有任务,总周数为:
total
- 如果最大任务数远大于其他项目任务总和,则受限于不能连续两周完成同一项目任务的规则,完成的最大周数为:
2 * rest + 1
这是因为最多你可以将其他项目的任务穿插在最大任务项目之间,每个其他项目任务都允许插入一个最大任务项目任务形成交替。这样形成的最长序列长度是 2 * rest + 1
。
解题方法
根据以上分析,算法很简单:
- 计算总任务数
total
和最大任务数max_m
。 - 计算剩余任务数
rest = total - max_m
。 - 如果
max_m <= rest + 1
,返回total
。 - 否则返回
2 * rest + 1
。
代码实现(Python)
from typing import List
class Solution:
def numberOfWeeks(self, milestones: List[int]) -> int:
total = sum(milestones)
max_m = max(milestones)
rest = total - max_m
if max_m <= rest + 1:
return total
else:
return 2 * rest + 1
复杂度分析
- 时间复杂度:O(n),遍历一次数组计算总和和最大值。
- 空间复杂度:O(1),使用常数额外空间。
示例说明
以示例 [5, 2, 1]
为例:
- 总任务数
total = 8
- 最大任务数
max_m = 5
(项目0) - 其余任务数
rest = 3
判断:
max_m <= rest + 1
→5 <= 3 + 1
→5 <= 4
,不成立
所以最大周数为:
2 * rest + 1 = 2 * 3 + 1 = 7
这和示例输出相符。
总结
这道题通过简单的数学推导和贪心思路,巧妙地解决了「不能连续两周做同一个项目」的限制。它归结为判断最大任务项目与其他任务项目的任务数量关系,从而推断最大可工作的周数。
掌握这类问题的思路,可以帮助你应对更多涉及任务调度和交替执行的限制类题目。