Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find minimum time required to complete tasks with k time gap between same type tasks in Python
Suppose we have a list of integers called tasks where each item represents a different task type, and a non-negative integer k. Each task takes one unit of time to complete and tasks must be completed in the given order, but we must have k units of time between executing two tasks of the same type. At any time, we can either execute a task or wait. We need to find the minimum time required to complete all tasks.
For example, if tasks = [0, 1, 1, 2] and k = 2, the output will be 6. The first two tasks are different types, so they execute without gaps. At time 2, the next task is type 1 (same as previous), so we wait 2 time slots, then execute it, followed by task type 2. The execution sequence is: [0, 1, wait, wait, 1, 2], requiring 6 time slots total.
Algorithm Steps
To solve this problem, we follow these steps −
-
tick := 0(current time) -
slot := {}(dictionary to track when each task type can next be executed) - For each task
tin tasks:- Get the earliest time this task type can be executed:
tf := slot[t] - If
tfexists andtf > tick, wait until that time:tick := tf - Execute the task:
tick := tick + 1 - Update when this task type can next be executed:
slot[t] := tick + k
- Get the earliest time this task type can be executed:
- Return
tick
Example
Let us see the following implementation to get better understanding −
def solve(tasks, k):
tick = 0
slot = {}
for t in tasks:
tf = slot.get(t)
if tf is not None and tf > tick:
tick = tf
tick += 1
slot[t] = tick + k
return tick
tasks = [0, 1, 1, 2]
k = 2
print(solve(tasks, k))
6
How It Works
Let's trace through the example step by step −
def solve_with_trace(tasks, k):
tick = 0
slot = {}
for i, t in enumerate(tasks):
tf = slot.get(t)
print(f"Task {i}: type {t}, current tick: {tick}")
if tf is not None and tf > tick:
print(f" Must wait until tick {tf}")
tick = tf
tick += 1
slot[t] = tick + k
print(f" Executed at tick {tick}, next available at tick {tick + k}")
print(f" Slot tracking: {slot}")
print()
return tick
tasks = [0, 1, 1, 2]
k = 2
result = solve_with_trace(tasks, k)
print(f"Total time required: {result}")
Task 0: type 0, current tick: 0
Executed at tick 1, next available at tick 3
Slot tracking: {0: 3}
Task 1: type 1, current tick: 1
Executed at tick 2, next available at tick 4
Slot tracking: {0: 3, 1: 4}
Task 2: type 1, current tick: 2
Must wait until tick 4
Executed at tick 5, next available at tick 7
Slot tracking: {0: 3, 1: 7}
Task 3: type 2, current tick: 5
Executed at tick 6, next available at tick 8
Slot tracking: {0: 3, 1: 7, 2: 8}
Total time required: 6
Key Points
- The algorithm maintains a dictionary
slotto track when each task type can next be executed - If a task type was recently executed, we must wait
ktime units before executing it again - Tasks of different types can be executed immediately if no waiting is required
- The time complexity is O(n) where n is the number of tasks
Conclusion
This algorithm efficiently calculates the minimum time needed to complete all tasks with the given constraints. It uses a greedy approach, executing tasks as soon as possible while respecting the cooldown period between same-type tasks.
