给定一组间隔:{1-4,6-7,10-12}添加一个新的间隔:(9,11),这样最终的解决方案就是‘合并’:输出:{1-4,6-7,9-12}。合并可能发生在双方(低范围和高范围)。
我看到这个问题在多个地方得到了回答,甚至有人建议使用Interval Tress,但没有解释他们将如何使用它。我所知道的唯一解决方案是按照开始时间的升序排列间隔,然后迭代它们,并尝试适当地合并它们。
如果有人能帮助我理解如何在这个用例中使用区间树,那就太好了!
我一直在关注CLRS书中的区间树,但它们并没有讨论合并,它们只讨论插入和搜索。
发布于 2013-01-27 17:01:55
(我假设这意味着间隔永远不能重叠,否则它们将被合并。)
要做到这一点,一种方法是存储平衡的二进制搜索树,范围的每个端点都有一个节点。然后,每个节点将被标记为标记间隔开始的“开放”节点或标记间隔结束的“关闭”节点。
插入新范围时,关于范围起始点将出现以下两种情况之一:
它已经在一个范围内,这意味着您将扩展一个已经存在的范围作为insertion.
要确定您所处的情况,您可以在树中对范围的起始点进行前置搜索。如果得到NULL或关闭节点,则需要插入一个新的打开节点来表示范围的起点。如果你得到一个开放的节点,你将继续延长这个时间间隔。
从那里,您需要确定范围延伸了多远。要执行此操作,请连续计算插入的初始节点的后续节点,直到发生以下情况之一:
,
通过天真的实现,这个算法的运行时间是O(log +k),其中n是间隔的数量,k是在这个过程中删除的间隔的数量(因为必须进行n次删除)。但是,您可以使用以下技巧将此速度提高到O(log )。由于删除过程总是删除序列中的节点,因此您可以使用端点的后续搜索来确定要删除的范围的终点。然后,您可以通过执行两个树拆分操作和一个树连接操作来拼接子范围以从树中删除。在合适的平衡树上(例如,红黑或张开),这可以在O(log )总时间内完成,如果要包含许多范围,则速度要快得多。
希望这能有所帮助!
发布于 2015-10-09 06:20:19
公共类MergeIntervals {
public static class Interval {
public double start;
public double end;
public Interval(double start, double end){
this.start = start;
this.end = end;
}
}
public static List<Interval> mergeInteval(List<Interval> nonOverlapInt, Interval another){
List<Interval> merge = new ArrayList<>();
for (Interval current : nonOverlapInt){
if(current.end < another.start || another.end < current.start){
merge.add(current);
}
else{
another.start = current.start < another.start ? current.start : another.start ;
another.end = current.end < another.end ? another.end : current.end;
}
}
merge.add(another);
return merge;
}
发布于 2013-01-27 16:32:25
看看这个。它可能会对你有所帮助:- http://www.boost.org/doc/libs/1_46_0/libs/icl/doc/html/index.html
该库提供以下功能:
1) interval_set
2) separate_interval_set
3) split_interval_set
https://stackoverflow.com/questions/14545695
复制相似问题