相交区间集合的最小划分问题:文献名称与最优高效算法咨询
嗨,这个问题在图论和区间算法领域有明确的对应名称,我来给你详细梳理一下~
问题的标准名称
这个问题等价于区间图的最小团覆盖问题。我们可以把每个区间看作区间图中的一个顶点:两个顶点之间有边,当且仅当对应的区间相交。你的需求就是用最少的「团」(团指两两之间都有边的顶点集合,也就是两两相交的区间集合)覆盖所有顶点,这正是最小团覆盖的定义。
另外,由于区间图属于完美图范畴,根据完美图定理,最小团覆盖的大小等于该区间图的最大独立集大小——这里的最大独立集指的是两两不相交的区间的最大数量(独立集里的顶点两两无关联,对应区间两两不相交)。
最优高效算法
既然最小团覆盖数等于最大独立集的大小,我们可以分两步解决这个问题:
步骤1:计算最小划分的子集数量(即最大独立集大小)
我们可以用经典贪心算法求最大独立集:
- 将所有区间按右端点从小到大排序;
- 初始化计数器为0,记录最后选中区间的右端点为
-∞; - 遍历排序后的区间:
- 如果当前区间的左端点大于最后选中区间的右端点(即两者不相交),就选中该区间,计数器加1,更新最后选中区间的右端点为当前区间的右端点;
- 最终的计数器值就是最大独立集的大小,也就是你需要的最小划分子集数量。
以你的例子验证:
排序后的区间是[1,2], [0,6], [0,7], [4,10], [5,10], [9,10]
- 选中
[1,2],计数器=1,最后右端点=2; - 跳过
[0,6](和[1,2]相交); - 跳过
[0,7](和[1,2]相交); - 选中
[4,10](左端点4>2),计数器=2,最后右端点=10; - 跳过后续所有和
[4,10]相交的区间;
最终计数器为2,对应最小划分子集数量为2,和你给出的最优结果一致。
步骤2:构造具体的划分子集
知道子集数量k后,我们可以用以下贪心方法构造划分:
- 同样将所有区间按右端点从小到大排序;
- 维护
k个子集,每个子集记录当前的「右端点最小值」(即该子集里所有区间右端点的最小者); - 遍历每个区间,将其加入第一个满足「当前区间的左端点 <= 该子集的右端点最小值」的子集,然后更新该子集的右端点最小值为
min(当前子集的右端点最小值, 当前区间的右端点)。
还是用你的例子验证:k=2,排序后的区间依次处理:
[1,2]加入第一个子集,子集1的右端点最小值=2;[0,6]满足0<=2,加入子集1,更新右端点最小值为min(2,6)=2;[0,7]满足0<=2,加入子集1,右端点最小值保持2;[4,10]不满足4<=2,加入子集2,子集2的右端点最小值=10;[5,10]不满足5<=2,加入子集2,右端点最小值保持10;[9,10]不满足9<=2,加入子集2,右端点最小值保持10;
最终得到的子集就是{[1,2], [0,6], [0,7]}和{[4,10], [5,10], [9,10]},和你给出的最优结果一致(子集内区间顺序不影响)。
这个算法的时间复杂度为O(n log n),主要来自排序步骤,后续遍历和分配都是线性时间,非常高效。
对你当前贪心算法的说明
你目前用的「每次找最大重叠区间作为子集」的策略为什么得不到最优解?因为这种策略优先选择覆盖最广的子集,但可能会把本可以分到同一个子集的区间拆分出去。比如你的例子里,[9,10]本可以和[4,10]、[5,10]分到一起,但你的算法可能先把[0,7],[0,6],[4,10],[5,10]作为一个子集(它们的重叠区域在[4,6]),剩下的[1,2]和[9,10]只能单独成子集,导致划分大小为3,显然不是最优解。所以选对贪心策略很关键~
备注:内容来源于stack exchange,提问作者J. M. Aziz

