1834. Single-Threaded CPU

้€™้กŒๅ…ถๅฏฆๆœ‰้ปž็ฎ—ๅฏฆไฝœ้กŒ, ้กŒ็›ฎๆœ‰ๆๅˆฐ

the CPU will choose the one with the shortest processing time. 
=> pq (small processingTimei, smallest index)

ๆ‰€ไปฅ่ฆ็”จ pq, ๅ› ็‚บ่ฆๅฐ time, index ๅšๆŽ’ๅบ, ๆ‰€ไปฅๅšไธ€ๅ€‹ class ๅ‡บไพ†ๅญ˜ๆœƒๆ˜ฏๆฏ”่ผƒๆผ‚ไบฎ็š„ไฝœๆณ•,

Queue<Task> queue = new PriorityQueue<>((a,b) -> {
            return a.processingTime == b.processingTime ? a.index - b.index : a.processingTime - b.processingTime;
        });

ๅ› ็‚บๆ˜ฏ็…งๆ™‚้–“้ †ๅบไพ†ๆ”พๅ…ฅ pq, ๆ‰€ไปฅ็•ถ็„ถ้–‹ๅง‹ๆ™‚้–“่ฆๅ…ˆๆŽ’ๅบ

Arrays.sort(jobs, (a,b) -> a.enqueueTime - b.enqueueTime);

ๆฏ”่ผƒไธๅฅฝ่จญ่จˆ็š„้ƒจๅˆ†ๆ˜ฏ, ๅฆ‚ไฝ•ๆŒ‰็…ง ๅ•Ÿๅ‹•ๆ™‚้–“ ๅ…ฅ pq ๅ‘ข๏ผŸ

from the name enqueueTime => hint us can add to queue

้‡้ปž่ฆๆœ‰ๅ€‹ curTime ไพ†่จ˜้Œ„็›ฎๅ‰ๆ™‚้–“ๅˆฐๅ“ช่ฃกไบ†, pq ๆ˜ฏ็ฉบ็š„ๆ™‚ๅ€™, ๆœƒ็ตฆไบˆๅˆๅ€ผ๏ผˆ็ฌฌไธ€ๅ€‹job ็š„่ตทๅง‹ๆ™‚้–“๏ผ‰

ๅ…ถไป– pq ๆœ‰ๅ…ƒ็ด ๆ™‚, ็•ถ็„ถๅฐฑๆ˜ฏๆ›ดๆ–ฐ็ตๆžœๅ’Œๆ›ดๆ–ฐ curTime (ๅŠ ไธŠ processingTime, ๅ› ็‚บ้€™ๆ˜ฏไธ€ๅ€‹ single thread ็š„ CPU, ไธ€ๆฌกๅšไธ€ไปถไบ‹)

from array to queue

ไนŸ็ถญๆŒไบ†ไธ€ๅ€‹ runIdx ไพ†่ฎ€ไธ‹ๅ€‹ job, ๆขไปถๆ˜ฏ ่ตทๅง‹ๆ™‚้–“ <= curTime

while()...้€™่ฃ

ๅฆ‚ๆญคๅฐฑๅฏไปฅๆŠŠ็ฌฆๅˆ่ตทๅง‹ๆ™‚้–“ ็š„job ๅ…ฅ pq

        int[] order = new int[n];
        int orderIdx = 0;
        int runIdx = 0;
        int curTime = 0;
        while (orderIdx < n) {
            
            while (runIdx < n && jobs[runIdx].enqueueTime <= curTime) {
                queue.offer(jobs[runIdx]);
                runIdx++;
            }
            // when no data in queue, curTime needs to refresh
            if (queue.isEmpty()) {
                curTime = jobs[runIdx].enqueueTime;
            } else {
                Task cur = queue.poll();
                order[orderIdx++] = cur.index;
                curTime += cur.processingTime;
            }
        }
        return order;

T: O(nlogn)
S: O(n)
class Solution {
    class Task {
        int index;
        int enqueueTime;
        int processingTime;
        Task(int index,
             int enqueueTime,
             int processingTime) {
            
            this.index = index;
            this.enqueueTime = enqueueTime;
            this.processingTime = processingTime;
        }
    }
    public int[] getOrder(int[][] tasks) {
        int n = tasks.length;
        Task[] jobs = new Task[n]; 
        for (int i = 0; i < n; i++) {
            jobs[i] = new Task(i, tasks[i][0], tasks[i][1]);
        }
        Arrays.sort(jobs, (a,b) -> a.enqueueTime - b.enqueueTime);
        
        Queue<Task> queue = new PriorityQueue<>((a,b) -> {
            return a.processingTime == b.processingTime ? a.index - b.index : a.processingTime - b.processingTime;
        });
        
        int[] order = new int[n];
        int orderIdx = 0;
        int runIdx = 0;
        int curTime = 0;
        while (orderIdx < n) {
            
            while (runIdx < n && jobs[runIdx].enqueueTime <= curTime) {
                queue.offer(jobs[runIdx]);
                runIdx++;
            }
            // when no data in queue, curTime needs to refresh
            if (queue.isEmpty()) {
                curTime = jobs[runIdx].enqueueTime;
            } else {
                Task cur = queue.poll();
                order[orderIdx++] = cur.index;
                curTime += cur.processingTime;
            }
        }
        return order;
    }
}

/*
tasks[i] = [enqueueTimei, processingTimei]

ith task
process at enqueueTimei, needs processingTimei


the CPU will choose the one with the shortest processing time. 
=> pq (small processingTimei, smallest index)

finished entire task


Return the order in which the CPU will process the tasks. (index)


[[1,2],[2,4],[3,2],[4,1]]


1. build task class
2. define pq

curTime = 0;
3. while (orderId < n) {
    while (runId < n && eTime <= curTime) {
        add to heap
        runId++
    }
    if (heap is empty) {
        init curTime = task[runId].eTime
    }
    
    heap pop, get cur task
    add to result[orderId++]
    curTime += cur task.proTime
    
}

T: O(nlogn)
S: O(n)
*/

Last updated