目录
完成所有任务的最少时间
题目描述:
你有一台电脑,它可以 同时 运行无数个任务。给你一个二维整数数组 tasks
,其中 tasks[i] = [starti, endi, durationi]
表示第 i
个任务需要在 闭区间 时间段 [starti, endi]
内运行 durationi
个整数时间点(但不需要连续)。
当电脑需要运行任务时,你可以打开电脑,如果空闲时,你可以将电脑关闭。
请你返回完成所有任务的情况下,电脑最少需要运行多少秒。
示例 1:
输入:tasks = [[2,3,1],[4,5,1],[1,5,2]] 输出:2 解释: - 第一个任务在闭区间 [2, 2] 运行。 - 第二个任务在闭区间 [5, 5] 运行。 - 第三个任务在闭区间 [2, 2] 和 [5, 5] 运行。 电脑总共运行 2 个整数时间点。
示例 2:
输入:tasks = [[1,3,2],[2,5,3],[5,6,2]] 输出:4 解释: - 第一个任务在闭区间 [2, 3] 运行 - 第二个任务在闭区间 [2, 3] 和 [5, 5] 运行。 - 第三个任务在闭区间 [5, 6] 运行。 电脑总共运行 4 个整数时间点。
提示:
1 <= tasks.length <= 2000
tasks[i].length == 3
1 <= starti, endi <= 2000
1 <= durationi <= endi - starti + 1
实现代码与解析:
贪心
class Solution {
public int findMinimumTime(int[][] tasks) {
Arrays.sort(tasks, (a, b) -> a[1] - b[1]); // 右端点排序
int res = 0;
boolean[] hash = new boolean[2010]; // 已经有任务运行的点
for (int[] t: tasks) {
int l = t[0];
int r = t[1];
int d = t[2];
for (int i = l; i <= r; i++) { // 先在已运行点上添加任务
if (hash[i]) d--;
}
while (d > 0) {
if (!hash[r]) {
hash[r] = true;
res++;
d--;
}
r--;
}
}
return res;
}
}
原理思路:
这种分段求最大或最小的题很明显就是贪心,贪心要么左端点排序,要么右端点排序,这题是右端点排序,贪心思路就是:尽可能在线段右侧运行任务,这样在后面的时间段就可以最大程度的复用前一个时间段已经运行任务的时间点。hash记录一下对于时间点有无任务在运行。