Assign tasks to workers with types and accounts
Task Scheduler Assignment
You are tasked with implementing a task scheduler responsible for assigning N tasks to W workers.
Task Details
Each task i (IDs 0 to N-1) arrives at a specific arrival[i] time (non-decreasing) and has the following attributes:
duration[i]: A positive integer representing the base duration of the task.type[i]: A string or integer label categorizing the task type.account[i]: A string or integer label identifying the account associated with the task.
Worker Details
Each worker w (IDs 0 to W-1) has the following attributes:
skills[w]: A set of task types that the worker is capable of processing.speed[w][t]: A positive integer representing the processing speed of workerwfor a task of typet. Iftis not inskills[w], the worker cannot process that task type.
When worker w runs task i of type t, the actual runtime is calculated as:
runTime(w, i) = duration[i] × speed[w][t]
A worker can process at most one task at a time. If a worker starts a task at time s, it becomes free again at time s + runTime.
Assignment Rules
Tasks must be processed in increasing task index order (i = 0 to N-1), which corresponds to their arrival order. For each task, a worker must be chosen based on the following priority rules:
-
Account Stickiness:
- Maintain a mapping
owner[account] -> workerIdfor accounts that have been assigned tasks previously. - If
owner[account[i]] = wexists and workerwsupportstype[i], then taskimust be assigned to workerw. - If the mapped worker
wdoes not supporttype[i], ignore this rule for the current task and proceed to Rule 2.
- Maintain a mapping
-
Fastest Eligible Worker:
- Among all workers that support
type[i], assign the task to the worker that will finish it earliest, assuming it starts as soon as possible. - The earliest start time for worker
wfor taskiisstart = max(arrival[i], nextFreeTime[w]). - The finish time for worker
wfor taskiisfinish = start + runTime(w, i). - Choose the worker with the minimum
(finish, workerId)lexicographically. This means prioritizing the earliest finish time, and then tie-breaking by choosing the worker with the smallerworkerId.
- Among all workers that support
-
Update Ownership:
- After assigning task
ito workerw, update theownermapping:owner[account[i]] = w.
- After assigning task
Output
Return an array assigned where assigned[i] is the workerId to which task i was assigned.
Constraints and Efficiency Expectations
W, N ≤ 2e5- The total number of
(worker, type)skill entries can be large. - Your solution should be efficient, avoiding a full scan of all workers for each task where possible.
AI interview prep
Core dilemma
Efficiently finding the optimal worker for each task under dynamic worker availability, complex priority rules (account stickiness vs. fastest worker), and large scale, specifically avoiding brute-force scans across all workers for every task.
3 tradeoffs and 3 stress tests locked
Interview prep
Unlock the interviewer X-Ray rubric, tradeoff matrix, stress tests, clarifying questions, and key concepts.
Assign tasks to workers with types and accounts
Task Scheduler Assignment
You are tasked with implementing a task scheduler responsible for assigning N tasks to W workers.
Task Details
Each task i (IDs 0 to N-1) arrives at a specific arrival[i] time (non-decreasing) and has the following attributes:
duration[i]: A positive integer representing the base duration of the task.type[i]: A string or integer label categorizing the task type.account[i]: A string or integer label identifying the account associated with the task.
Worker Details
Each worker w (IDs 0 to W-1) has the following attributes:
skills[w]: A set of task types that the worker is capable of processing.speed[w][t]: A positive integer representing the processing speed of workerwfor a task of typet. Iftis not inskills[w], the worker cannot process that task type.
When worker w runs task i of type t, the actual runtime is calculated as:
runTime(w, i) = duration[i] × speed[w][t]
A worker can process at most one task at a time. If a worker starts a task at time s, it becomes free again at time s + runTime.
Assignment Rules
Tasks must be processed in increasing task index order (i = 0 to N-1), which corresponds to their arrival order. For each task, a worker must be chosen based on the following priority rules:
-
Account Stickiness:
- Maintain a mapping
owner[account] -> workerIdfor accounts that have been assigned tasks previously. - If
owner[account[i]] = wexists and workerwsupportstype[i], then taskimust be assigned to workerw. - If the mapped worker
wdoes not supporttype[i], ignore this rule for the current task and proceed to Rule 2.
- Maintain a mapping
-
Fastest Eligible Worker:
- Among all workers that support
type[i], assign the task to the worker that will finish it earliest, assuming it starts as soon as possible. - The earliest start time for worker
wfor taskiisstart = max(arrival[i], nextFreeTime[w]). - The finish time for worker
wfor taskiisfinish = start + runTime(w, i). - Choose the worker with the minimum
(finish, workerId)lexicographically. This means prioritizing the earliest finish time, and then tie-breaking by choosing the worker with the smallerworkerId.
- Among all workers that support
-
Update Ownership:
- After assigning task
ito workerw, update theownermapping:owner[account[i]] = w.
- After assigning task
Output
Return an array assigned where assigned[i] is the workerId to which task i was assigned.
Constraints and Efficiency Expectations
W, N ≤ 2e5- The total number of
(worker, type)skill entries can be large. - Your solution should be efficient, avoiding a full scan of all workers for each task where possible.