FastPrepIn-Memory Priority Task Scheduler

In-Memory Priority Task Scheduler

Rippling logoRippling● MediumINTERNPHONE SCREEN

Problem statement

Design an in-memory task scheduler. It starts empty. Process the operations in operations in order. For each index i, taskIds[i] and priorities[i] hold the values used by operations[i].

  • "insert": add a pending task with ID taskIds[i] and priority priorities[i].
  • "delete": remove the pending task with ID taskIds[i]. If no pending task has that ID, nothing happens.
  • "execute": run the pending task with the highest priority and remove it from the scheduler. Record its ID. If no task is pending, record -1.

A larger number means a higher priority. If several pending tasks share the highest priority, the one that was inserted earliest runs first.

After a task runs or is deleted, its ID may be inserted again. That insert creates a new task with its own priority and its own insertion time.

Return the recorded values of all "execute" operations, in order. If there are no "execute" operations, return an empty array.

Follow-up: Can you make every operation take O(log n) time? How would your design change if the scheduler had to hold millions of tasks?

Function

runTaskScheduler(operations: String[], taskIds: int[], priorities: int[]) → int[]

Examples

Example 1

operations = ["insert","insert","insert","execute","delete","execute","execute"]taskIds = [1,2,3,0,1,0,0]priorities = [5,9,5,0,0,0,0]return = [2,3,-1]

Task 2 has the highest priority, 9, so the first execute runs it. Deleting task 1 leaves only task 3, which the second execute runs. The last execute finds no pending task and records -1.

Example 2

operations = ["insert","insert","insert","execute","insert","execute","execute","execute"]taskIds = [7,4,9,0,7,0,0,0]priorities = [3,3,3,0,1,0,0,0]return = [7,4,9,7]

Tasks 7, 4, and 9 all have priority 3, so they run in the order they were inserted. After task 7 runs, ID 7 is inserted again as a new task with priority 1. That new task has the lowest priority, so it runs last.

Example 3

operations = ["insert","delete","delete","insert","insert","execute","execute"]taskIds = [5,8,5,5,6,0,0]priorities = [10,0,0,-2,-7,0,0]return = [5,6]

Deleting task 8 does nothing because no pending task has that ID. Task 5 is deleted, then inserted again with priority -2; its old priority 10 no longer counts. Since -2 is larger than -7, task 5 runs before task 6.

Constraints

  • 1 <= operations.length <= 10^4
  • taskIds.length == operations.length
  • priorities.length == operations.length
  • Each operations[i] is "insert", "delete", or "execute".
  • 0 <= taskIds[i] <= 10^9
  • -10^9 <= priorities[i] <= 10^9
  • If operations[i] is "insert" or "delete", then taskIds[i] >= 1.
  • If operations[i] is "execute", then taskIds[i] == 0.
  • If operations[i] is "delete" or "execute", then priorities[i] == 0.
  • An "insert" never uses the ID of a task that is still pending.

More Rippling problems

See Rippling hiring insights
Saved
public int[] runTaskScheduler(String[] operations, int[] taskIds, int[] priorities) {
    // Write your solution here.
}
Checking account…