批量处理任务
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 501 ms, 内存: 70.3 MB
/*
题目思路:
1. 将所有任务根据结束时间进行排序。
2. 使用一个Set来记录已经选择的时间点。
3. 遍历每一个任务,通过Stream的filter和limit方法选择合适的时间点。
4. 返回最终选择的时间点数量。
*/
import java.util.*;
import java.util.stream.*;
public class TaskSchedulerStream {
public int minTime(int[][] tasks) {
Arrays.sort(tasks, (a, b) -> a[1] - b[1]); // 按结束时间排序
Set<Integer> chosenTimes = new HashSet<>();
for (int[] task : tasks) {
int start = task[0], end = task[1], period = task[2];
List<Integer> availableTimes = IntStream.rangeClosed(start, end)
.boxed()
.sorted(Comparator.reverseOrder())
.filter(time -> !chosenTimes.contains(time))
.limit(period)
.collect(Collectors.toList());
chosenTimes.addAll(availableTimes);
}
return chosenTimes.size();
}
public static void main(String[] args) {
TaskSchedulerStream scheduler = new TaskSchedulerStream();
int[][] tasks = {{1, 3, 2}, {2, 5, 3}, {5, 6, 2}};
System.out.println(scheduler.minTime(tasks)); // 输出:4
}
}
解释
方法:
该题解利用了排序和栈的结构来解决问题。首先,将任务按照结束时间进行排序,这样可以按顺序处理每个任务,并尽可能地减少开机时间。使用一个栈来存储已经处理的时间段,栈中的元素形式为(start, end, total),其中start和end表示当前连续的开机时间段,total是截至当前时间的总开机时间。对每个任务,算法尝试将它的运行时间安排在已有的时间段中,如果现有时间段不足以满足任务的需求,则从任务的结束时间向前扩展新的时间段。通过这样的处理,可以确保每个任务在其允许的时间范围内得到处理,并且总的开机时间是最短的。
时间复杂度:
O(n log n)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么在栈中使用了一个哨兵元素(-2, -2, 0),它在算法中具体起到了什么作用?
▷🦆
代码中存在`while end - stack[-1][1] <= d`的循环判断,该循环的目的是什么?在什么情况下会结束循环?
▷