This problem simulates a CPU scheduler. We have a set of tasks, each arriving at a specific time and taking a specific duration. The CPU is single-threaded, so it handles one task at a time. When it finishes a task (or starts idle), it picks the next task from all currently available tasks using a specific priority: shortest processing time first, and if there's a tie, the smaller original index wins.
The complication is that tasks arrive at different times. While the CPU is busy processing one task, new tasks may become available. A single sort by processing time is not enough, because availability depends on the current time, and the current time advances by different amounts depending on which task we picked. We have to track which tasks are available at each decision point, and those decision points shift as the CPU runs.
So at each moment the CPU finishes a task, we need the available task with the smallest processing time (and smallest index as a tiebreaker). A min-heap (priority queue) gives us that minimum in logarithmic time.
1 <= n <= 10^5 -> With up to 100,000 tasks, O(n^2) would be 10^10 operations, which is too slow. We need O(n log n) or better.1 <= enqueueTime_i, processingTime_i <= 10^9 -> Times can be very large. We can't iterate through every unit of time. We must jump between events.Simulate the CPU's behavior step by step. At each decision point, when the CPU becomes idle, scan through all tasks to find which ones are available, then pick the one with the shortest processing time and smallest index among them.
Each time the CPU finishes a task, we look at every task, check whether its enqueue time has passed, skip any already-processed tasks, and pick the best candidate from the rest. If nothing is available yet, we fast-forward the clock to the next arrival rather than stepping through every unit of time.
The repeated full scan is what makes this quadratic. Sorting tasks by arrival time lets us add new arrivals with a single forward-moving pointer, and a min-heap keeps the shortest available task one operation away.
The brute force is slow at two things: finding available tasks and picking the best one. Two data structures fix both.
First, sort the tasks by enqueue time. Now arrivals can be consumed in order with a single pointer. Instead of scanning all tasks to check availability, we advance the pointer until every task that has arrived by the current time has been added.
Second, use a min-heap (priority queue) to hold the available tasks, ordered by (processing time, original index). Extracting the minimum gives the next task the CPU would pick.
The loop runs like this. When the CPU finishes a task, advance the current time, push any newly arrived tasks into the heap, then pop the top element. If the heap is empty but tasks remain, the CPU is idle, so jump the clock forward to the next arrival.
Two invariants hold every time we pop from the heap. First, every task with enqueue time <= currentTime is either in the heap or already processed, because the pointer pushes each arrival before we pop. Second, the heap orders by (processingTime, originalIndex), so its top is exactly the task the CPU rules select. Since currentTime only ever increases, a task that was unavailable at one pop can only become available later, never the reverse, so we never miss an eligible task. Together these guarantee the popped sequence matches the CPU's schedule.
currentTime = 0 and use pointer i = 0 to track the next task to enqueue.