计算包含另一个间隔的间隔数?

时间:2016-02-08 07:54:10

标签: algorithm optimization intervals divide-and-conquer inversion

给定两个列表,每个列表包含N个间隔(数字行的子集),每个间隔具有起点和终点的形式。一个列表中有多少对这些区间包含来自另一个列表的区间?

例如:

如果列表A是{(1,7), (2,9)}而列表B是{(3,6), (5,8)}

然后,A的间隔包含B中的间隔的对数将是3对:

(1,7),(3,6)
(2,9)(3,6)
(2,9)(5,8)

目标是射击O(n log n)。

我的算法目前首先按x坐标排序,然后将其作为一个列表。然后按y坐标对列表进行排序,并计算两个列表之间的反转。但我的问题是为什么这有效?任何见解都将不胜感激。

我目前可视化的方式是以下几何方式(其中每个线的交点都是num反转的计数):

enter image description here

注意:我不确定如何检查列表列表中的反转。只是试图获得一个给出O(n log n)的方法。如果有任何其他方法乐于听取建议。

2 个答案:

答案 0 :(得分:1)

如果您决定尝试使用树/网格方法,我将解释它是如何工作的。对于您的任务,您不需要2D,而是需要一维间隔图甚至网格。让我们选择网格,因为它更清晰。

假设您的对是从1到100的整数。那么您可以负担得到一个大小为100的数组。数组中的每个单元格都包含空集(有序列表)。见下图:

enter image description here

现在我们开始在网格中添加间隔。我们在2,9之间的所有网格单元中的1,7和2之间的所有网格销售中添加1(1,2是ID,我们在每个插入的间隔增加1,以这种方式插入是低效的但是这可以是固定的)。

现在我们如何检查B的间隔?我们只从第一个单元格中获取每个ID,并检查它是否也在第二个单元格中。由于单元格已设置,因此检查采用O(log n)。在最坏的情况下,我们需要n O(log n)运算来检查B中一个区间在A内的重叠区间计数。

这可以扩展为使用区间图而不是网格(如果数字不是小整数)。此外,如果您在A中有固定数量的间隔,并且没有内存要求,例如,如果我们用数组替换集合,则O(logN)可以变为O(1)。

答案 1 :(得分:1)

我将回答有关为什么带有反转的解决方案有效的第一个问题。首先,我将澄清一件事。你不应该计算所有的反转(线的交叉点),而只计算A列表中的元素和B列表中的元素之间的相交。在您的示例中没有区别,但我们假设A = {(1,7), (2,5)}B = {(3,6), (5,8)}。如果我们在你的例子中可视化这些情况,那么将有2个交叉点,但我们正在寻找的只有1对,即(1,7),(3,6)。

现在让我们假设我们有两个时间间隔:I1=(x1,y1)I2=(x2,y2)I2中包含I1。这意味着x1 <= x2y1 >= y2。现在,如果您按x排序间隔列表,则I1将始终位于I2之前。类似地,如果您按y选择间隔列表,则I1将始终位于I2之后。如果我们将第一个列表中的I1I2I1I2连接在第二个列表中,那么该行也必须交叉。

但是,我们假设x1 <= x2y1 < y2。现在,I1将位于第一个和第二个列表中的I2之前。如果我们将第一个列表中的I1I2I1I2连接在第二个列表中,那么这些行将永远不会交叉。如果x1 > x2y1 >= y2

,则情况相同

以下是这些案例的可视化:

相关问题