批量处理任务
题目描述:
某实验室计算机待处理任务以 [start,end,period] 格式记于二维数组 tasks,
表示完成该任务的时间范围:为起始时间 start 至结束时间 end 之间,需要计算机投入 period 的时长,
注意:
period 可为不连续时间
首尾时间均包含在内
处于开机状态的计算机可同时处理任意多个任务,请返回电脑最少开机多久,可处理完所有任务。
提示:
2 <= tasks.length <= 10^5
tasks[i].length == 3
0 <= tasks[i][0] <= tasks[i][1] <= 10^9
1 <= tasks[i][2] <= tasks[i][1]-tasks[i][0] + 1
输入输出描述:
输入描述:
一个二维数组
输出描述:
电脑最少开机多久
示例1:
输入:
tasks = [[1,3,2],[2,5,3],[5,6,2]]
输出:
4
解释:
tasks[0] 选择时间点 2、3;
tasks[1] 选择时间点 2、3、5;
tasks[2] 选择时间点 5、6;
因此计算机仅需在时间点 2、3、5、6 四个时刻保持开机即可完成任务。
示例2:
输入:
tasks = [[2,3,1],[5,5,1],[5,6,2]]
输出:
3
解释:
tasks[0] 选择时间点 2 或 3;
tasks[1] 选择时间点 5;
tasks[2] 选择时间点 5、6;
因此计算机仅需在时间点 2、5、6 或 3、5、6 三个时刻保持开机即可完成任务。
解题思路:
本题同LeetCode上的原题LCP 32. 批量处理任务;较优的解题思路在题解里面可以查看,本题的代码也是来自己LeetCode灵神的题解。
采用贪心策略:尽可能的让两个任务之间的运行时间重叠。
1、先对任务按照结束时间进行排序
2、开辟一个长度为最大的结束时间的数组run,为了标记在那些时刻在运行中
3、从排序后的任务列表开始遍历:
对于当前任务,从结束时间开始可查看那些时间已经在run数组中(即在这写时间点的时间可算作该任务的运行时间)。
若任务的所有运行时间都能够从run中减掉,则说明当前任务可与之前的那些任务进行并行运行,不需额外的时间。
若任务还需要额外的时间进行才能运行结束。开启额外的时间时,优先开启靠近结束时间、且未在run中的时间点,这样可以尽可能的与后面的任务时间重叠,减少总的运行时间。
代码:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String line = scanner.nextLine();
int index = line.indexOf("[");
String[] split = line.substring(index + 2, line.length() - 2).replace("],[", "#").split("#");
int n = split.length;
int[][] tasks = new int[n][3];
// 输入处理
for (int i = 0; i < n; i++) {
String[] tmp = split[i].split(",");
tasks[i][0] = Integer.parseInt(tmp[0]);
tasks[i][1] = Integer.parseInt(tmp[1]);
tasks[i][2] = Integer.parseInt(tmp[2]);
}
// 按照每个任务的 end 时间点进行排序
Arrays.sort(tasks, (a, b)->a[1] - b[1]);
// 以最后一个任务的结束时间为长度,创建一个:标记计算机在某时间点是否在运行
boolean[] run = new boolean[tasks[n - 1][1] + 1];
int res = 0;
for (int[] item : tasks) {
// 任务的起始时间、结束时间、运行时间
int start = item[0];
int end = item[1];
int period = item[2];
// 从任务的的结束时间开始遍历,减去已经运行掉的时间
for (int i = end; i >= start && period > 0; i--) {
if (run[i]) {
period--;
}
}
// 如果该任务还需要额外的时间才能运行结束,优先开启靠结束时间近的时间点
for (int i = end; i >= start && period > 0; i--) {
if (!run[i]) {
run[i] = true;
period--;
res++;
}
}
}
// 统计运行的时间
System.out.println(res);
}