Job Scheduling with Deadlines in DSA Python - Time & Space Complexity
We want to understand how the time needed to schedule jobs changes as we add more jobs.
How does the scheduling process grow when the number of jobs increases?
Analyze the time complexity of the following code snippet.
jobs = [(2, 100), (1, 19), (2, 27), (1, 25), (3, 15)] # (deadline, profit)
jobs.sort(key=lambda x: x[1], reverse=True)
result = [False] * max(job[0] for job in jobs)
for deadline, profit in jobs:
for slot in range(min(deadline, len(result)) - 1, -1, -1):
if not result[slot]:
result[slot] = True
break
This code schedules jobs by profit, trying to place each job before its deadline.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The nested loops where for each job we try to find a free slot before its deadline.
- How many times: Outer loop runs once per job (n times), inner loop can run up to the maximum deadline (d times).
As the number of jobs (n) grows, and the maximum deadline (d) grows, the total steps increase roughly by n times d.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 (jobs), d=5 | About 50 checks |
| 100 (jobs), d=20 | About 2000 checks |
| 1000 (jobs), d=100 | About 100,000 checks |
Pattern observation: Operations grow roughly by multiplying number of jobs and maximum deadline.
Time Complexity: O(n * d)
This means the time needed grows by the number of jobs times the maximum deadline.
[X] Wrong: "The scheduling always takes O(n log n) time because of sorting only."
[OK] Correct: Sorting is just one part; the nested loops to find slots can take much more time depending on deadlines.
Understanding how nested loops affect time helps you explain your approach clearly and shows you can analyze real scheduling problems.
"What if we used a data structure to find free slots faster? How would the time complexity change?"
Practice
Job Scheduling with Deadlines problem?Solution
Step 1: Understand the problem goal
The problem aims to schedule jobs so that each job finishes before its deadline.Step 2: Identify the optimization criteria
We want to maximize the total profit earned from scheduled jobs, not just the count.Final Answer:
Maximize the total profit by scheduling jobs before their deadlines -> Option BQuick Check:
Goal = Maximize profit [OK]
- Thinking it's about scheduling all jobs regardless of profit
- Confusing deadline with job duration
- Assuming jobs can be scheduled after deadlines
(job_id, deadline, profit).Solution
Step 1: Identify the sorting key
Profit is at index 2 in each job tuple, so key=lambda x: x[2] is correct.Step 2: Sort in descending order
Use reverse=True to sort profits from highest to lowest.Final Answer:
jobs.sort(key=lambda x: x[2], reverse=True) -> Option AQuick Check:
Sort by profit descending = jobs.sort(key=lambda x: x[2], reverse=True) [OK]
- Sorting by deadline instead of profit
- Forgetting reverse=True for descending order
- Using wrong tuple index for profit
jobs = [(1, 4, 20), (2, 1, 10), (3, 1, 40), (4, 1, 30)]
jobs.sort(key=lambda x: x[2], reverse=True)
slots = [False] * 4
result = [None] * 4
for job in jobs:
for j in range(min(4, job[1]) - 1, -1, -1):
if not slots[j]:
slots[j] = True
result[j] = job[0]
break
print(result)Solution
Step 1: Sort jobs by profit descending
Sorted jobs: (3,1,40), (4,1,30), (1,4,20), (2,1,10)Step 2: Schedule jobs in latest available slot before deadline
Job 3: deadline 1, slot 0 free -> assign slot 0 = 3 Job 4: deadline 1, slot 0 taken, no earlier slot -> skip Job 1: deadline 4, slots 3 to 0 checked, slot 3 free -> assign slot 3 = 1 Job 2: deadline 1, slot 0 taken, no earlier slot -> skipFinal Answer:
[3, None, None, 1] -> Option AQuick Check:
Result = [3, None, None, 1] [OK]
- Assigning jobs to earliest slot instead of latest
- Not sorting jobs by profit first
- Confusing slot indices with deadlines
jobs = [(1, 2, 100), (2, 1, 19), (3, 2, 27), (4, 1, 25), (5, 3, 15)]
jobs.sort(key=lambda x: x[2]) # Sort by profit ascending
slots = [False] * 3
result = [None] * 3
for job in jobs:
for j in range(min(3, job[1])):
if not slots[j]:
slots[j] = True
result[j] = job[0]
break
print(result)Solution
Step 1: Check sorting order
Jobs are sorted by profit ascending, which schedules low profit jobs first.Step 2: Understand scheduling impact
Scheduling low profit jobs first reduces total profit; sorting must be descending.Final Answer:
Jobs are sorted by profit ascending instead of descending -> Option DQuick Check:
Sort order must be descending for max profit [OK]
- Sorting by ascending profit
- Iterating slots forward instead of backward (less critical here)
- Ignoring slot size mismatch
[(1, 2, 100), (2, 1, 19), (3, 2, 27), (4, 1, 25), (5, 3, 15)], what is the maximum total profit achievable by scheduling jobs before their deadlines? Assume each job takes 1 unit time and only one job can be scheduled at a time.Solution
Step 1: Sort jobs by profit descending
Sorted jobs: (1,2,100), (3,2,27), (4,1,25), (2,1,19), (5,3,15)Step 2: Schedule jobs in latest free slot before deadline
Job 1: deadline 2, assign slot 2 (index 1) Job 3: deadline 2, assign slot 1 (index 0) Job 4: deadline 1, slot 0 taken, skip Job 2: deadline 1, slot 0 taken, skip Job 5: deadline 3, assign slot 3 (index 2)Step 3: Calculate total profit
Scheduled jobs: 1 (100), 3 (27), 5 (15) Total profit = 100 + 27 + 15 = 142Final Answer:
142 -> Option CQuick Check:
Total profit = 142 [OK]
- Scheduling jobs without sorting by profit
- Assigning jobs to earliest slot instead of latest
- Counting jobs beyond deadline slots
Ready to prove it?
Pass the test and this pattern moves unknown
