完成所有任务的最少时间
难度:
标签:
题目描述
There is a computer that can run an unlimited number of tasks at the same time. You are given a 2D integer array tasks
where tasks[i] = [starti, endi, durationi]
indicates that the ith
task should run for a total of durationi
seconds (not necessarily continuous) within the inclusive time range [starti, endi]
.
You may turn on the computer only when it needs to run a task. You can also turn it off if it is idle.
Return the minimum time during which the computer should be turned on to complete all tasks.
Example 1:
Input: tasks = [[2,3,1],[4,5,1],[1,5,2]] Output: 2 Explanation: - The first task can be run in the inclusive time range [2, 2]. - The second task can be run in the inclusive time range [5, 5]. - The third task can be run in the two inclusive time ranges [2, 2] and [5, 5]. The computer will be on for a total of 2 seconds.
Example 2:
Input: tasks = [[1,3,2],[2,5,3],[5,6,2]] Output: 4 Explanation: - The first task can be run in the inclusive time range [2, 3]. - The second task can be run in the inclusive time ranges [2, 3] and [5, 5]. - The third task can be run in the two inclusive time range [5, 6]. The computer will be on for a total of 4 seconds.
Constraints:
1 <= tasks.length <= 2000
tasks[i].length == 3
1 <= starti, endi <= 2000
1 <= durationi <= endi - starti + 1
代码结果
运行时间: 54 ms, 内存: 17.1 MB
/*
* Problem Description:
* You have a computer that can run an infinite number of tasks simultaneously. Given a 2D integer array 'tasks' where tasks[i] = [start_i, end_i, duration_i] indicates that the i-th task needs to run for 'duration_i' integer time points within the closed interval [start_i, end_i]. You can turn the computer on when a task needs to run and turn it off when idle. Return the minimum number of seconds the computer needs to run to complete all tasks.
*
* Approach:
* 1. Sort the tasks by their end time to ensure we can use the latest possible time points.
* 2. Use a priority queue to track the current running tasks and their end times.
* 3. Traverse through the tasks, updating the priority queue and calculating the required run times.
*/
import java.util.*;
import java.util.stream.*;
public class MinRunTimeStream {
public int minRunTime(int[][] tasks) {
Arrays.sort(tasks, Comparator.comparingInt(task -> task[1]));
PriorityQueue<Integer> pq = new PriorityQueue<>();
int[] currentTime = {0};
Arrays.stream(tasks).forEach(task -> {
int start = task[0];
int end = task[1];
int duration = task[2];
IntStream.range(0, duration).forEach(i -> {
if (!pq.isEmpty() && pq.peek() < start) {
currentTime[0] = pq.poll();
} else {
currentTime[0] = Math.max(currentTime[0], start);
}
pq.offer(currentTime[0]++);
});
});
return pq.size();
}
public static void main(String[] args) {
MinRunTimeStream mrt = new MinRunTimeStream();
int[][] tasks = {{2, 3, 1}, {4, 5, 1}, {1, 5, 2}};
System.out.println(mrt.minRunTime(tasks)); // Output: 2
}
}
解释
方法:
此题解使用贪心算法和区间合并策略,首先按照任务的结束时间对所有任务进行排序,确保我们总是优先处理最早结束的任务。使用一个栈来维护不重叠的运行时间段,栈中的每个元素记录当前任务的开始和结束时间以及截止当前任务的总运行时间。对于每个任务,我们检查它与栈中现有运行时间段的重叠情况,并计算还需运行的时间。如果当前任务的需求时间未被满足,我们会利用最后一个任务的结束时间与当前任务的结束时间之间的空隙来填充。这种方法确保了在满足所有任务的前提下,电脑的运行时间尽可能少。
时间复杂度:
O(n log n)
空间复杂度:
O(n)
代码细节讲解
🦆
在题解中提到使用二分查找来处理任务,这里的二分查找是如何实现的?具体是基于哪些条件进行查找的?
▷🦆
请解释代码中`d -= stack[-1][2] - s`和`d -= r - start + 1 if start <= r else 0`这两行代码的具体作用和计算逻辑。
▷