这道题是 LeetCode 2589. 完成所有任务的最少时间,属于区间贪心 + 扫描线类型的问题。

题目理解

你有 n 个任务,每个任务:

· 必须在时间区间 [start, end] 内运行
· 需要运行 duration 个单位时间(可以非连续运行)

目标:安排所有任务的运行时间点,使得所有任务都完成,并且总运行时间点数量最少(即最少需要多少个整数时间点)。

核心思路

贪心策略:

1. 按结束时间升序排序任务
2. 对于每个任务,尽量把运行时间点安排在靠近结束时间的位置
3. 用一个布尔数组标记哪些时间点已经被占用
4. 计算当前任务还需运行的时间(减去已占用的时间点)
5. 从后往前分配剩余的时间点

代码实现

```java
class Solution {
    public int findMinimumTime(int[][] tasks) {
        // 按结束时间升序排序
        Arrays.sort(tasks, (a, b) -> a[1] - b[1]);
        
        // 标记时间点是否被占用(题目没给范围,最多到2000左右)
        boolean[] used = new boolean[2001];
        int total = 0;
        
        for (int[] task : tasks) {
            int start = task[0];
            int end = task[1];
            int duration = task[2];
            
            // 先统计在当前区间内已经有多少个被占用的时间点
            int alreadyUsed = 0;
            for (int i = start; i <= end; i++) {
                if (used[i]) {
                    alreadyUsed++;
                }
            }
            
            // 还需要新占用的时间点
            int need = duration - alreadyUsed;
            if (need <= 0) continue;
            
            // 从后往前分配未占用的时间点(贪心:尽量靠后放)
            for (int i = end; i >= start && need > 0; i--) {
                if (!used[i]) {
                    used[i] = true;
                    need--;
                    total++;
                }
            }
        }
        
        return total;
    }
}
```

复杂度分析

· 时间复杂度:O(n × M),其中 n 是任务数,M 是时间范围(本题上限约 2000)
· 空间复杂度:O(M)

示例验证

```java
// 示例1
输入: tasks = [[2,3,1],[4,5,1],[1,5,2]]
输出: 3
解释: 可以安排在时间点 1, 3, 5

// 示例2  
输入: tasks = [[1,3,2],[2,5,3],[5,6,2]]
输出: 4
解释: 可以安排在时间点 2,3,5,6
```

优化思路

如果时间范围很大(10^9),可以用差分数组 + 优先队列或并查集优化,但本题数据范围较小,上述解法足够。

关键点总结

1. 排序:按结束时间升序是贪心正确性的基础
2. 从后往前分配:优先占用区间靠后的时间,为前面的任务留出更多可用时间
3. 避免重复计算:用布尔数组记录已选时间点

这样就能用最少的运行时间点完成所有任务。

 

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐