You want to schedule a list of jobs in d days. Jobs are dependent (i.e To work on the ith job, you have to finish all the jobs j where 0 <= j < i).
You have to finish at least one task every day. The difficulty of a job schedule is the sum of difficulties of each day of the d days. The difficulty of a day is the maximum difficulty of a job done on that day.
You are given an integer array jobDifficulty and an integer d. The difficulty of the ith job is jobDifficulty[i].
Return the minimum difficulty of a job schedule. If you cannot find a schedule for the jobs return -1.
Example 1:
Input: jobDifficulty = [6,5,4,3,2,1], d = 2 Output: 7 Explanation: First day you can finish the first 5 jobs, total difficulty = 6. Second day you can finish the last job, total difficulty = 1. The difficulty of the schedule = 6 + 1 = 7
Example 2:
Input: jobDifficulty = [9,9,9], d = 4 Output: -1 Explanation: If you finish a job per day you will still have a free day. you cannot find a schedule for the given jobs.
Example 3:
Input: jobDifficulty = [1,1,1], d = 3 Output: 3 Explanation: The schedule is one job per day. total difficulty will be 3.
Constraints:
1 <= jobDifficulty.length <= 3000 <= jobDifficulty[i] <= 10001 <= d <= 10Problem Overview: You receive an array jobDifficulty where each value represents the difficulty of a job, and an integer d representing the number of days. Jobs must be done in order, and at least one job must be scheduled each day. The difficulty of a day equals the maximum difficulty among jobs done that day. The goal is to split the array into d contiguous groups so the sum of daily difficulties is minimized.
Approach 1: Recursive Approach with Memoization (Time: O(n^2 * d), Space: O(n * d))
This approach models the problem as a decision at each job index: where should the current day's schedule end? For a starting index i and remaining days k, iterate forward and assign jobs i..j to the current day. Track the running maximum difficulty for that segment. The remaining jobs j+1..n-1 must then be scheduled in k-1 days. Use recursion to explore these splits and store results in a memo table keyed by (index, daysRemaining). Memoization avoids recomputing overlapping states. This turns an exponential recursion into polynomial time. The nested iteration over possible cut points results in O(n^2 * d) time.
Approach 2: Dynamic Programming with Bottom-Up Approach (Time: O(n^2 * d), Space: O(n * d))
The bottom-up dynamic programming version builds the same state iteratively. Define dp[i][k] as the minimum difficulty to schedule the first i jobs across k days. For each state, try all possible last-day partitions: iterate backward from job i and track the maximum difficulty of the segment assigned to the final day. Combine this value with dp[j-1][k-1], which represents scheduling the earlier jobs in fewer days. Update the minimum across all valid splits. The iteration order ensures smaller subproblems are already computed. This DP formulation avoids recursion overhead and is typically preferred in production code.
The key insight across both approaches is that the difficulty of a day depends only on the maximum job difficulty in its segment. By iterating possible segment boundaries and maintaining a running maximum, you efficiently evaluate every valid partition while reusing results for overlapping subproblems. This structure makes the problem a classic application of dynamic programming over a linear array.
Recommended for interviews: Interviewers expect the dynamic programming formulation. Start by describing the recursive partition idea because it clearly explains the state and transition. Then convert it into bottom-up DP for an optimal O(n^2 * d) solution with O(n * d) space. Showing both demonstrates understanding of recursion, memoization, and iterative DP design.
This approach uses a dynamic programming (DP) table to calculate the minimum difficulty schedule. The DP table is constructed such that dp[i][j] represents the minimum difficulty for scheduling the first i jobs in j days. We aim to fill this DP table using a bottom-up approach, iterating over all possible job and day combinations. For each combination, we calculate the scenario where the last day covers a range of jobs and obtains the minimum difficulty possible.
This implementation initializes a 2D DP table where dp[i][j] keeps track of the minimum difficulty for the first i jobs scheduled in j days. We iterate day by day and within each day, iterate over the possible jobs that can be scheduled. For each possible subarray, we calculate the maximum difficulty and adjust the DP table accordingly.
Time Complexity: O(n2d), where n is the length of jobDifficulty and d is the number of days.
Space Complexity: O(nd), due to the storage of minimum difficulties in the DP table.
This approach is based on recursion with memoization. The main idea is to use a recursive function to find the minimum difficulty from a given starting index, splitting the jobs over the remaining days. For each recursive call, consider different partitions for the first day's job and compute the best possible schedule using range maximum queries and storing results to avoid redundant calculations.
This implementation utilizes a recursive depth-first search (DFS) function to handle the subproblem, memorizing results as each substate is calculated. The search accumulates the maximum difficulty for each possible partition of jobs for current day.
Time Complexity: O(n2d), with memoization reducing redundant calculations.
Space Complexity: O(nd), storing calculated subproblems and recursion frames.
We define f[i][j] as the minimum difficulty to finish the first i jobs within j days. Initially f[0][0] = 0, and all other f[i][j] are infty.
For the j-th day, we can choose to finish jobs [k,..i] on this day. Therefore, we have the following state transition equation:
$
f[i][j] = min_{k \in [1,i]} {f[k-1][j-1] + max_{k leq t leq i} {jobDifficulty[t]}}
The final answer is f[n][d].
The time complexity is O(n^2 times d), and the space complexity is O(n times d). Here n and d$ are the number of jobs and the number of days respectively.
Python
Java
C++
Go
TypeScript
| Approach | Complexity |
|---|---|
| Dynamic Programming with Bottom-Up Approach | Time Complexity: O(n2d), where Space Complexity: O(nd), due to the storage of minimum difficulties in the DP table. |
| Recursive Approach with Memoization | Time Complexity: O(n2d), with memoization reducing redundant calculations. Space Complexity: O(nd), storing calculated subproblems and recursion frames. |
| Dynamic Programming | — |
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Recursive with Memoization | O(n^2 * d) | O(n * d) | Good for understanding the partition decision process and explaining the recurrence during interviews. |
| Bottom-Up Dynamic Programming | O(n^2 * d) | O(n * d) | Preferred implementation for coding interviews and production because it avoids recursion overhead. |
Minimum Difficulty of a Job Schedule | Recursion | Memoization | Amazon | Leetcode 1335 • codestorywithMIK • 89,157 views views
Watch 9 more video solutions →Practice Minimum Difficulty of a Job Schedule with our built-in code editor and test cases.
Practice on FleetCodePractice this problem
Open in Editor