Problem
You are given a set of n
jobs, given as arrays:
deadline[]
: An array wheredeadline[i]
represents the deadline of jobi
and deadline (di ≥ 1),profit[]
: An array whereprofit[i]
represents the profit for completing jobi
and profitpi
(pi ≥ 0).
Only one job can be scheduled at a time, and each job takes exactly 1 unit of time. You earn profit for a job only if you complete it before or on its deadline. The task is to find the subset of jobs that maximises the total profit while adhering to deadlines.
Examples
Example 1
|
|
Example 2
|
|
Solution
Method 1 - Sorting + Greedy
Reasoning/intuition
- To maximise profit, prioritise jobs with higher profits. Hence, sort the jobs in descending order of profit.
- Use a greedy approach to schedule the highest-profit jobs first, checking the latest available timeslots (near to their deadlines).
- Keep track of which timeslots are already booked.
Algorithm
- Combine the
deadline
andprofit
arrays into a single list of tuples(profit, deadline, index)
for easier handling. - Sort this list by profit in descending order.
- Find the maximum deadline to create a scheduling array.
- Use slots (timing) for job scheduling, where you choose the latest available slot for each job and maximise profits greedily.
Code
|
|
|
|
|
|
|
|
|
|
|
|
Complexity
- ⏰ Time complexity:
O(n log n + n * d)
forn
jobs and max deadline asd
- Sorting the jobs:
O(n * log(n))
. - For each job, checking available slots:
O(n * d)
whered
is the maximum deadline. - Overall:
O(n * log(n) + n * d)
.
- Sorting the jobs:
- 🧺 Space complexity:
O(n + d)
. For storing the job list (input) and scheduling array:O(n + d)
.
Method 2 - Using disjoint set
Reasoning
- Since each job has a fixed deadline, we aim to execute it before or at its deadline. Once a time slot
t
is used, we need to find the next available free time slott-1
for scheduling. - Using disjoint sets, we can dynamically and efficiently track the parent (next available slot) for the time slots.
Steps
-
Sort jobs by profit:
- Arrange all jobs in descending order of profit. This ensures we always prioritise the jobs with the highest profit while scheduling.
-
Find the maximum deadline
d_max
:- Determine the maximum deadline of any job. This allows us to restrict our search space for available time slots to the range
[1, d_max]
.
- Determine the maximum deadline of any job. This allows us to restrict our search space for available time slots to the range
-
Create disjoint sets:
- Initialise a disjoint set array, where each index represents a time slot, and its value points to the next available slot. Initially:
parent[i] = i (each slot points to itself initially)
- Initialise a disjoint set array, where each index represents a time slot, and its value points to the next available slot. Initially:
-
Process each job:
- Iterate through the sorted jobs (highest-profit first). For each job:
- Find the maximum available time slot ≤ the job’s deadline using the Find operation of the disjoint set.
- If a slot is available:
- Schedule the job in that slot.
- Update the parent of the current slot to point to its previous slot (
t-1
) using the Union operation. This ensures the next time slot for future jobs is correctly tracked.
- Iterate through the sorted jobs (highest-profit first). For each job:
Key Intuition of Disjoint Set Operations
-
Find operation:
- For a given slot, the Find operation helps locate the farthest available time up to that slot (e.g., if slot
5
is occupied, it points to4
). This prevents unnecessary linear scans for available times.
- For a given slot, the Find operation helps locate the farthest available time up to that slot (e.g., if slot
-
Union operation:
- When a slot
t
is occupied, we “union” it witht-1
to specify thatt
is no longer independent and refers to the next available slot (t-1
).
- When a slot
Code
|
|
|
|
|
|
Complexity
- ⏰ Time complexity:
O(n log n)
- Sorting the jobs by profit (descending) takes
O(n * log(n))
. - Disjoint Set Operations:
- The
Find
andUnion
operations both have an amortised time complexity ofO(α(n))
, whereα(n)
is the inverse Ackermann function, which grows very slowly (effectively constant for most practical purposes). - Each job involves one Find and one Union operation. For
n
jobs, this amounts toO(n)
disjoint set operations in total.
- The
- Sorting the jobs by profit (descending) takes
- 🧺 Space complexity:
O(n + d_max)
- Disjoint set array for
d_max
time slots:O(d_max)
. - Storage for jobs:
O(n)
.
- Disjoint set array for