1. 问题背景与核心挑战
这道LeetCode困难题1335描述了一个典型的工作计划调度优化问题:我们需要将n个任务分配到d天中完成,每个任务有对应的难度值。每天的难度定义为当天完成的所有任务中的最大难度值,而整个计划的难度则是所有天难度的总和。我们的目标是找到所有可能分配方案中的最小总难度。
这个问题看似简单,但隐藏着几个关键挑战:
- 任务必须按原始顺序分配,不能重新排序
- 每天至少分配一个任务
- 需要同时考虑局部(每日)和全局(整体)的最优解
- 随着任务数和天数增加,暴力解法的时间复杂度会急剧上升
我在实际解决这个问题时,发现它非常适合用动态规划(DP)来高效求解。下面我将详细拆解这个问题的解决思路和具体实现。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 动态规划解法思路拆解
2.1 状态定义与转移方程
定义dp[i][j]表示前i个任务在j天内完成的最小总难度。我们的目标是求dp[n][d],即所有n个任务在d天内的最小总难度。
状态转移方程需要考虑:
- 第j天可以处理的任务范围(从k到i,其中k >= j-1)
- 当天处理的子数组的最大难度
- 前j-1天处理前k-1个任务的最小总难度
具体方程为:
dp[i][j] = min(dp[i][j], dp[k-1][j-1] + max(jobDifficulty[k..i]))
2.2 边界条件处理
需要特别注意几个边界情况:
- 当任务数n小于天数d时,无法满足每天至少一个任务的条件,直接返回-1
- 当d=1时,必须一天完成所有任务,总难度就是所有任务的最大值
- 初始化dp数组时,dp[0][0] = 0,其他初始值设为无穷大
2.3 时间复杂度分析
这个DP解法有三层循环:
- 遍历天数(1到d)
- 遍历任务数(1到n)
- 遍历可能的分割点k
因此总时间复杂度为O(n^2 * d),空间复杂度为O(n * d)。考虑到题目约束n和d最大为300,这个复杂度是可以接受的。
3. 详细实现步骤与代码解析
3.1 基础版本实现
python复制def minDifficulty(jobDifficulty, d):
n = len(jobDifficulty)
if n < d:
return -1
