用最少区间覆盖[0,target]需按左端点升序、右端点降序排序,遍历中贪心选择当前能覆盖covered且右端点最大的区间,若断连则返回-1,否则返回所选数量。

在 Java 中,用数组实现贪心算法解决区间覆盖问题,核心在于按右端点排序 + 贪心选择最远可达的区间。目标是用最少数量的区间覆盖指定范围(如 [0, target]),前提是给定的区间集合确实能覆盖该范围。
明确问题与前提条件
典型场景:给定一个目标长度 target(即需覆盖 [0, target]),以及若干闭区间 intervals[i] = [start, end](均为 int 数组),要求选出最少数量的区间,使其并集完整覆盖 [0, target]。
关键前提:
- 所有区间必须满足 start ≤ end;
- 至少存在一种方式覆盖 [0, target],否则返回 -1;
- 区间可重叠,但不能“跳过”任何位置——例如 [0,2] 和 [3,5] 无法覆盖 [0,5],因为缺了 2 到 3 之间的点(2.5 或整数 3 前的空隙)。
数组表示与预处理步骤
Java 中用 int[][] intervals 存储原始区间。贪心前必须做两件事:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
立即学习“Java免费学习笔记(深入)”;
- 过滤无效区间:剔除 end target 的区间(对覆盖 [0,target] 无贡献);
-
按左端点升序、右端点降序排序:使用
Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]) != 0 ? Integer.compare(a[0], b[0]) : Integer.compare(b[1], a[1])),确保相同起点时优先选更长的; - 排序后,用普通 for 循环遍历数组,无需额外数据结构。
贪心主逻辑(纯数组遍历实现)
维护两个变量:covered(当前已覆盖到的最右位置,初始为 0),count(已选区间数,初始为 0)。遍历时:
- 跳过所有 start > covered 的区间(出现空隙,不可接续);
- 在所有 start ≤ covered 的区间中,找出最大的 end(即能向右延伸最远的那个);
- 一旦当前区间 start > 上一轮确定的 covered,就选定刚才找到的最大 end 区间,covered = maxEnd,count++;
- 若某轮找不到任何 start ≤ covered 的区间(即 maxEnd 没更新),说明断连,返回 -1;
- 当 covered ≥ target,循环结束,返回 count。
示例:target=6,intervals = {{0,2},{1,4},{3,5},{4,6}} → 排序后仍同序;第一轮 covered=0,候选 [0,2] 和 [1,4],选 end=4;第二轮 covered=4,候选 [3,5],[4,6],选 end=6;6≥6,返回 2。
代码片段(无额外类/集合,仅数组+循环)
public static int minIntervalCount(int[][] intervals, int target) {
if (target == 0) return 0;
Arrays.sort(intervals, (a, b) ->
Integer.compare(a[0], b[0]) != 0 ?
Integer.compare(a[0], b[0]) :
Integer.compare(b[1], a[1]));
int covered = 0, count = 0, i = 0, n = intervals.length;
while (covered < target && i < n) {
int maxEnd = covered;
// 扫描所有左端点 <= covered 的区间,记录最大右端点
while (i < n && intervals[i][0] <= covered) {
maxEnd = Math.max(maxEnd, intervals[i][1]);
i++;
}
if (maxEnd == covered) return -1; // 无法推进
covered = maxEnd;
count++;
}
return covered >= target ? count : -1;
}

















