在给定两个区间列表的情况下,得到重叠区间的数量
get the number of overlapping intervals, given two lists of intervals
我最近遇到了一个有趣的问题:
给定两个区间列表,从这两个列表中找出重叠区间的总数。
Example
L1: ([1,2][2,3][4,5][6,7])
L2: ([1,5][2,3][4,7][5,7])
[1,5] overlaps [1,2] [2,3] [4,5]
[2,3] overlaps [1,2] [2,3]
[4,7] overlaps [4,5] [6,7]
[5,7] overlaps [4,5] [6,7]
total = 3+2+2+2 = 9
显然,蛮力方法是有效的,但它太慢了(我需要比O(n^2)更好的方法)。
我也喜欢这里类似的问题。但这并不完全一样。。。
感谢提供的任何帮助
用成对的(value; +1 or -1 for start and end of interval)
生成两个排序列表。
两个计数器—Count1
和Count2
,显示第一个和第二个列表中的活动间隔数。
以合并方式浏览这两个列表。
当您从第一个列表中获得配对时,带有+1-增量Count1
当您从第一个列表中获得具有-1的配对时,递减Count1
并将Count2
添加到结果中
第二个列表中的对也是如此
最后阶段的伪代码
CntA = 0
CntB = 0
Res = 0
ia = 0
ib = 0
while (ia < A.Length) and (ib < B.Length)
if Compare(A[ia], B[ib]) <= 0
CntA = CntA + A[ia].Flag
if (A[ia].Flag < 0)
Res = Res + CntB
ia++
else
CntB = CntB + B[ib].Flag
if B[ib].Flag < 0
Res = Res + CntA
ib++
微妙时刻——比较if Compare(A[ia], B[ib]) <= 0
在这里,我们还应该考虑标志-正确处理端点只接触[1.2][2..3]的情况(您将这种情况视为相交)。所以排序和合并比较器都应该取这样的合成值:3 * A[ia].Value - A[ia].Flag
。通过这种比较,区间的起始点在区间结束前用相同的坐标进行处理。
p.S.在Delphi中进行了快速测试。适用于给定的数据集和一对其他数据集。
Delphi代码(ideone FPC由于泛型原因没有编译它)
尝试寻找扫描线算法,它将为您提供最快的解决方案。
您可以在TopCoder网站查看简短描述,或观看Robert Sedgwick的视频。这些描述了一个更难的问题,但应该给你一个如何解决你的问题的方法。
实际上,主要的想法是每次更新特殊交叉列表中的分段列表时,遍历分段的开始和结束的排序列表。
对于此任务,每个原始列表将分别有两个交集列表。开始时,两个交叉点列表都为空。当越过线段的起点时,将其添加到适当的交叉点列表中,它显然与其他交叉点列表的所有线段相交。当到达线段的末端时,只需将其从交点列表中删除即可。
这个算法将给你O(n log(n))的速度,在最坏的情况下,O(n)的内存。
您可以在第二个数组上的循环中使用std::set_intersection来将其与第一个数组中的每个项匹配。但我不确定性能是否符合你的要求。
我最近在处理一个类似的问题时偶然发现了区间树ADT——我怀疑它对您有用,无论您是否实现它。
它基本上是一个三元树,我用包含以下内容的节点构建了它:
- 包含小于当前节点的间隔的左子树
- 包含超过当前节点的间隔的右侧子树
- 重叠间隔列表
- 包含所有重叠区间的区间值
在O(n*log(n))
中构建树后,用于检查重叠间隔的查询函数应为O(log(n) + m)
,其中m
是报告的重叠间隔数。
注意在创建时,按间隔中的结束值排序和拆分列表应该有助于保持平衡。
- 在没有太多条件句的情况下,我如何避免被零除
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 在未初始化映射的情况下,将值插入到映射的映射中
- 是默认情况下分配给char数组常量的值
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 如何在不产生任何垃圾的情况下获得C中的像素
- 在已经使用Git的情况下减少编译时间
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 如何在没有信号的情况下从C++执行QML插槽
- 如何在不知道向量大小的情况下输入向量内部的向量?
- 为什么在某些情况下不写入此文件?
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 在没有Xcode的情况下在Mac捆绑包中嵌入框架
- UE4-如何在给定4个屏幕坐标的情况下缩放纹理或材质
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 在C++中如何在没有pow的情况下进行基础计算
- 松弛原子与无同步情况下的记忆连贯性
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 我是c ++的新手,你能解释一下在这种情况下的指针吗
- 在给定两个区间列表的情况下,得到重叠区间的数量