Skip to content

Commit fc749ac

Browse files
committed
feat(algorithms, heap): minimum machines to schedule tasks
1 parent 780f9dc commit fc749ac

27 files changed

+132
-0
lines changed

algorithms/heap/__init__.py

Whitespace-only changes.
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Schedule Tasks on Minimum Machines
2+
3+
We are given an input array, tasks, where tasks[i]=[starti ,endi] represents the start and end times of n tasks. Our
4+
goal is to schedule these tasks on machines given the following criteria:
5+
6+
- A machine can execute only one task at a time.
7+
- A machine can begin executing a new task immediately after completing the previous one.
8+
- An unlimited number of machines are available.
9+
10+
Find the minimum number of machines required to complete these n tasks.
11+
12+
## Constraints
13+
14+
- n == `tasks.length`
15+
- 1 <= `tasks.length` <= 10^3
16+
- 0 <= `tasksi.start` < `tasksi.end` <= 10^4
17+
18+
## Examples
19+
20+
![Example 1](images/examples/schedule_tasks_on_minimum_machines_example_1.png)
21+
![Example 2](images/examples/schedule_tasks_on_minimum_machines_example_2.png)
22+
![Example 3](images/examples/schedule_tasks_on_minimum_machines_example_3.png)
23+
![Example 4](images/examples/schedule_tasks_on_minimum_machines_example_4.png)
24+
25+
## Solution
26+
27+
The core intuition for solving this problem is to allocate tasks to the minimum number of machines by reusing machines
28+
whenever possible. The algorithm efficiently manages machine availability by sorting tasks by their start times and using
29+
a min heap to track end times. If the earliest available machine (top of the heap) finishes before or as a task starts,
30+
it is reused and removed from the heap. Otherwise, a new machine is allocated, and the current task’s end time is pushed
31+
into the heap. The heap size at the end represents the minimum number of machines required.
32+
33+
Using the intuition above, we implement the algorithm as follows:
34+
35+
1. Sort the tasks array by the start time of each task to process them in chronological order.
36+
2. Initialize a min heap (machines) to keep track of the end times of tasks currently using machines.
37+
3. Iterate over each task in the sorted tasks array.
38+
- Extract the start and end times of the current task.
39+
- Check if the machine with the earliest finish time is free, i.e., top of machines is less than or equal to the
40+
current task’s start time. If it is, remove it from the heap, as the machine can be reused.
41+
- Push the end time of the current task into the heap, indicating that a machine is now in use until that time.
42+
4. After processing all tasks, return the size of the heap, which represents the minimum number of machines required.
43+
44+
![Solution 1](images/solutions/schedule_tasks_on_minimum_machines_solution_1.png)
45+
![Solution 2](images/solutions/schedule_tasks_on_minimum_machines_solution_2.png)
46+
![Solution 3](images/solutions/schedule_tasks_on_minimum_machines_solution_3.png)
47+
![Solution 4](images/solutions/schedule_tasks_on_minimum_machines_solution_4.png)
48+
![Solution 5](images/solutions/schedule_tasks_on_minimum_machines_solution_5.png)
49+
![Solution 6](images/solutions/schedule_tasks_on_minimum_machines_solution_6.png)
50+
![Solution 7](images/solutions/schedule_tasks_on_minimum_machines_solution_7.png)
51+
![Solution 8](images/solutions/schedule_tasks_on_minimum_machines_solution_8.png)
52+
![Solution 9](images/solutions/schedule_tasks_on_minimum_machines_solution_9.png)
53+
![Solution 10](images/solutions/schedule_tasks_on_minimum_machines_solution_10.png)
54+
![Solution 11](images/solutions/schedule_tasks_on_minimum_machines_solution_11.png)
55+
![Solution 12](images/solutions/schedule_tasks_on_minimum_machines_solution_12.png)
56+
![Solution 13](images/solutions/schedule_tasks_on_minimum_machines_solution_13.png)
57+
![Solution 14](images/solutions/schedule_tasks_on_minimum_machines_solution_14.png)
58+
![Solution 15](images/solutions/schedule_tasks_on_minimum_machines_solution_15.png)
59+
![Solution 16](images/solutions/schedule_tasks_on_minimum_machines_solution_16.png)
60+
![Solution 17](images/solutions/schedule_tasks_on_minimum_machines_solution_17.png)
61+
![Solution 18](images/solutions/schedule_tasks_on_minimum_machines_solution_18.png)
62+
![Solution 19](images/solutions/schedule_tasks_on_minimum_machines_solution_19.png)
63+
64+
### Time Complexity
65+
66+
The time complexity of the above algorithm is O(nlogn), where n is the number of tasks represented by the length of the
67+
tasks array. This is because:
68+
69+
- Sorting the array takes O(nlogn).
70+
- The total cost for heap operations is O(nlogn) because we process n tasks, and each operation on the min-heap has a
71+
time complexity of O(logn).
72+
73+
Therefore, the overall time complexity is O(nlogn).
74+
75+
### Space Complexity
76+
77+
The algorithm’s space complexity is O(n) because the min heap can grow up to a maximum size of n if every task requires
78+
a separate machine.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from typing import List
2+
from heapq import heappush, heappop, heapify
3+
4+
5+
def minimum_machines(tasks: List[List[int]]) -> int:
6+
# sort tasks by their start time in place, Time cost is O(n log(n)) with space cost being O(n) due to timsort
7+
tasks.sort(key=lambda x: x[0])
8+
9+
# initialize a min heap to keep track of the end times
10+
machines: List[int] = []
11+
heapify(machines)
12+
13+
for current_task in tasks:
14+
task_start, task_end = current_task
15+
# check if a machine with the earliest finish time is free
16+
if machines and machines[0] <= task_start:
17+
# reuse machine
18+
heappop(machines)
19+
20+
# assign a machine to the current task
21+
heappush(machines, task_end)
22+
# Return the size of the heap representing the minimum number of machines required
23+
return len(machines)
81.6 KB
Loading
51.2 KB
Loading
59.8 KB
Loading
96.5 KB
Loading
58.3 KB
Loading
66.8 KB
Loading
84 KB
Loading

0 commit comments

Comments
 (0)