单线程 CPU
难度:
标签:
题目描述
代码结果
运行时间: 358 ms, 内存: 54.1 MB
/*
* Solution Approach (Java Stream API):
* 1. Create a stream of tasks with indexes and sort by enqueue time.
* 2. Use a PriorityQueue to manage tasks based on processing time and index.
* 3. Process tasks by advancing time and adding eligible tasks to the queue.
* 4. Execute tasks and record the order using a stream.
* 5. Convert the result list to an array.
*/
import java.util.*;
import java.util.stream.*;
class Solution {
public int[] getOrder(int[][] tasks) {
int n = tasks.length;
// Step 1: Sort tasks by enqueue time
List<int[]> sortedTasks = IntStream.range(0, n)
.mapToObj(i -> new int[]{tasks[i][0], tasks[i][1], i})
.sorted((a, b) -> a[0] - b[0])
.collect(Collectors.toList());
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[1] == b[1] ? a[2] - b[2] : a[1] - b[1]);
int time = 0, index = 0;
List<Integer> result = new ArrayList<>();
while (index < n || !pq.isEmpty()) {
while (index < n && sortedTasks.get(index)[0] <= time) {
pq.offer(sortedTasks.get(index++));
}
if (pq.isEmpty()) {
time = sortedTasks.get(index)[0];
continue;
}
int[] current = pq.poll();
time += current[1];
result.add(current[2]);
}
return result.stream().mapToInt(i -> i).toArray();
}
}
解释
方法:
该题解采用的是模拟CPU任务调度的方式。首先,通过索引排序,以确保任务按照入队时间被正确处理。使用优先队列(小顶堆)来管理和选择当前可执行的任务,依据是任务的执行时间和索引顺序。算法从模拟时间为0开始,遍历所有任务。如果当前没有任务可以执行,时间会跳转到下一个任务的入队时间。当有一个或多个任务可以执行时,会将它们按照执行时间推入优先队列中。每次从队列中取出执行时间最短的任务进行执行,并更新时间戳。通过这种方式,我们可以模拟CPU的操作过程,并按顺序记录每个任务的执行。
时间复杂度:
O(n log n)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么使用优先队列(小顶堆)而不是其他数据结构如列表或链表来实现任务的选择和执行?
▷