Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 在间隔列表中搜索间隔重叠?_Algorithm - Fatal编程技术网

Algorithm 在间隔列表中搜索间隔重叠?

Algorithm 在间隔列表中搜索间隔重叠?,algorithm,Algorithm,假设[a,b]表示实线上从a到b的间隔,ax和a

假设[a,b]表示实线上从a到b的间隔,a 你能把它们分成两个列表吗?一个是间隔开始的列表,另一个是间隔结束的列表

通过这种方式,您可以将y与间隔开始列表中的项目进行比较(比如通过二进制搜索),从而在此基础上减少候选项

然后可以将x与“间隔结束”列表中的项目进行比较

编辑

案例:一次性

如果你在一次性情况下只比较单个时间间隔和时间间隔列表,我不相信排序能帮你解决问题

通过对所有的x进行线性搜索以剔除任何不可能的间隔,然后对剩余的y进行另一次线性搜索,您可以减少您的总工作量。虽然这仍然是O(n),但如果没有这一点,您将进行2n次比较,而平均而言,您只能以这种方式进行(3n-1)/2次比较

我相信这是最好的,你可以做一个未排序的名单

案例:预排序不算数


如果您将重复将单个间隔与此间隔列表进行比较,并对列表进行预排序,则可以获得更好的结果。上述过程仍然适用,但通过对第一个列表进行二进制搜索,然后对第二个列表进行二元搜索,您可以得到O(m log n),而不是O(mn),其中m是正在比较的单个间隔的数量。注意,仍然提供了减少总比较的优势。[2m log n与m(3(log n)-1)/2相比]

您可以同时按左端和右端进行排序,并使用两个列表来消除无重叠值。如果列表按左端排序,则测试范围右端右侧的间隔都不能重叠。如果列表按右端排序,则左端左侧的间隔都不能重叠测试范围的所有部分可能重叠

例如,如果间隔为

[1,4], [3,6], [4,5], [2,8], [5,7], [1,2], [2,2.5]
您发现与
[3,4]
重叠,然后按测试的左端排序并标记右端的位置(右端刚好大于其值,因此
4
包含在范围内)

您知道
[5,7]
不能重叠,然后按测试的右端排序并标记左端的位置

[1,2], [2,2.5], *, [1,4], [4,5], [3,6], [5,7], [2,8]
你知道
[1,2]
[2,2.5]
不能重叠

不确定这样做的效率有多高,因为您必须进行两次排序和搜索。

A是一种数据结构,通常用于提高二维碰撞检测的效率

我认为你可以想出一个类似的一维结构。这需要一些预先计算,但会导致O(logn)性能

基本上,从覆盖所有可能间隔的根“节点”开始,当向树中添加节点时,您可以决定它是落在中点的左侧还是右侧。如果它穿过中点,您可以将其分成两个间隔(但记录原始父节点)你可以对树的深度设置一个限制,这可以节省内存和提高性能,但会让事情变得复杂一些(你需要在节点中存储一个间隔列表)


然后,在检查间隔时,基本上可以找到插入该间隔时将插入的所有叶节点,检查这些节点内的部分间隔是否相交,然后将记录的间隔报告为“原始”父节点。

[a,b]与[x,y]重叠iff b>x和a正如您在其他答案中所看到的,大多数算法都是与一种特殊的数据结构。例如,对于作为输入的未排序的间隔列表,
O(n)
是您得到的最好的数据结构(通常更容易根据指定算法的数据结构进行思考)

在这种情况下,您的问题不完整:

  • 你有完整的清单吗,还是你自己创造的

  • 您只需要执行一个或多个这样的查找吗

  • 您对它应该支持的操作及其频率有什么估计吗

例如,如果您只需要执行一次这样的查找,那么之前对列表进行排序是不值得的。如果需要进行多次排序,则更昂贵的排序或生成“1D四叉树”将被摊销

然而,这将很难解决,因为一个简单的四叉树(据我所知)只能检测碰撞,但它不能创建与输入重叠的所有段的列表


一个简单的实现是一个有序的(按coordonate)列表,在其中插入所有带有标志start/end和段号的段结束。这样,通过解析它(仍然是O(n),但如果您还需要重叠的所有段的列表,我怀疑您是否可以加快速度),并跟踪在“检查点”未关闭的所有打开的段。

为了完整性起见,我想补充一点,对于这类问题,有一个众所周知的数据结构,称为(惊喜,惊喜)。它基本上是一个扩展的平衡树(红黑,AVL,您选择)它存储按其左(低)端点排序的间隔。扩展是每个节点在其子树中存储最大的右(高)端点。此树允许您在O(logn)时间内查找所有重叠间隔


CLRS 14.3中对其进行了描述。

+1,因为它使我的工作日变得更加有趣。但是交叉点不是需要O(n)个时间吗?如果列表长度为n个元素,则
[1,2], [2,2.5], *, [1,4], [4,5], [3,6], [5,7], [2,8]