Problem Description
Given two arrays – servers and tasks – assign each task to a server according to the following rules: at each second j, the jth task is added to the queue; while the queue is not empty and free servers exist, take the task at the front and assign it to the available server with the smallest weight (breaking ties by smallest index). If no server is free, wait until the next server finishes its current task. A server that starts task j at time t becomes free at time t + tasks[j]. Return an array ans where ans[j] is the index of the server which processes the jth task.
Key Insights
- Use a min-heap to track free servers sorted by weight and index.
- Use another min-heap to manage busy servers, prioritized by when they become free.
- Keep track of the current time, taking into account task arrival times.
- If no server is free at the time of task arrival, fast-forward time to when the next server becomes available.
- Always reassign servers from the busy heap to the free heap when they complete their tasks.
Space and Time Complexity
Time Complexity: O(m log n), where m is the number of tasks and n is the number of servers, since each task assignment may require heap operations. Space Complexity: O(n + m) primarily for the heaps and the result array.
Solution
We use two heaps:
- Free Servers Heap: stores tuples (server weight, server index), sorted so that the server with the smallest weight (and then smallest index) is always at the top.
- Busy Servers Heap: stores tuples (finish time, server weight, server index), ordered by finish time. When a server is busy processing a task, it resides in this heap. The algorithm maintains a current time variable. For each task arriving at time j, time is updated to ensure it is at least j. Servers that become free on or before the current time are moved from the busy heap to the free heap. If no free server is available, the current time jumps to the finish time of the next server to be available. The task is then assigned to the free server at the top of the free heap, and the server's next free time is computed and added to the busy heap. This continues until all tasks are assigned.