检查数组之间重叠的算法

时间:2016-05-05 18:02:27

标签: arrays algorithm sorting

我有两个阵列,一个现有的约会和一个潜在的约会。每个数组都包含现有或潜在约会的值/到值。每个数组中的约会已按时间排序。

我需要检查每个现有约会的每个潜在约会,看看没有重叠。我知道我可以从现有的约会开始每次,但我正在寻找一种更有效的方式。

4 个答案:

答案 0 :(得分:1)

想法:开始将第一个间隔相互比较。如果一个间隔完全在另一个间隔之前,请查看下一个间隔,直到找到重叠或后续的间隔。间隔A完全在间隔B之前,或者B完全在A之前,或者它们以某种方式重叠。找到重叠后,您可以退出查找。这可以很容易地返回最早的重叠对,但返回所有重叠对将需要更多的工作。

伪代码:

Overlaps(actual[1..n], pending[1..m])
    i = 1
    j = 1
    while i <= n and j <= m do
        if actual[i].stop <= pending[j].start then
            i = i + 1
        else if actual[i].start >= pending[j].stop then
            j = j + 1
        else
            return true
    return false

注意 - 如果您要查找所有重叠对,而不是在检测到第一次重叠后退出,则可以打印ij并增加i {{1}如果actual[i].stop <= pending[j].stop,则增加j。这将最终打印每个重叠对,仍然是线性时间。

答案 1 :(得分:1)

这可以在O(nlogn)中有效地完成。考虑两个分别包含现有和潜在约会的数组A, B。按约会结束时间(A)和约会开始时间(A_end)的递增顺序对A_start进行排序。这需要O(nlogn)时间

B中每个潜在的约会:
s =作业的起点
t =作业的结束点

现在,在数组A_startA_end上进行二进制搜索,以查找在s-t之间取o(logn)时间的所有约会。
[#Overlaps =
(结束时间&lt; = t的约会) - (约会结束时间&lt; s)+
(结束时间&gt; t的约会) - (约会开始时间&gt; t)+
]

因此,整体订单为O(nlogn)

编辑:#overlaps = sum_1 + sum_2
这里sum_1表示具有结束时间&lt; = t的那些间隔。但是再一次只找到重叠的间隔,我们必须用结束时间&lt;秒。因此,我们只得到那些结束时间> = s且&lt; = t。的人 这里sum_2表示具有结束时间&gt;的那些间隔。吨。但是再一次只找到重叠的间隔,我们必须用结束时间&gt;减去那些间隔。吨。因此,我们仅获得具有结束时间> t但是开始时间&lt; = t的那些。

证明可以通过以下事实给出:任何重叠间隔可以具有结束时间&lt; = t或&gt; t。因此它将位于sum_1或sum_2。

答案 2 :(得分:0)

您可以将现有和潜在约会的并集合并为一个数组,并按开始时间对联合进行排序。在间隔中添加标签,以便您知道它是现有的或可能的间隔。 (您也可以在单独的数组中对它们进行排序并增加两个索引,但代码更简单,只有一个列表。)

然后,您可以遍历组合数组,并在它们重叠时将相邻区间合并在一起。仅将现有约会与具有潜力的现有约会和潜在约会合并。为此,您必须记住最近的现有和潜在的间隔。

这样,您不需要回到最开始,只需要查看最近合并的时间间隔。

在psedudocode中:

E: existing appointments
P: potential appointments

A: union of P and E, sorted by start time

lastE = []
lastP = []
for each appointment a in A:
    if a is existing:
        if a overlaps with lastE:
            lastE = lastE + [a]
        else
            lastE = [a]
        if a overlaps with lastP:
            print all appointments in lastP overlapping with a
    if a is potential:
        if a overlaps with lastE:
            print a
        if a overlaps with lastP:
            lastP = lastP + [a]
        else:
            lastP = [a]

请注意,您无需存储lastE的结构,您可以将其定义为单个间隔并调整开始和结束时间。

您需要知道lastP中的个别约会。您可以通过在lastP中按结束时间维持降序来进一步优化它。然后,当打印alastP之间的所有重叠时,您可以在lastP中潜在约会的结束时间小于{{的开始时间时停止查看1}}。

答案 3 :(得分:0)

如果我们首先加入这两个数组并且加入所需的时间是O(n)然后我们对整个数组进行排序,如果我们使用快速排序或合并排序,那么这个排序需要O(nlogn)然后我们计算总数时间的复杂性,就像这样

F(n)= O(n)+ O(nlogn)

因此最终的复杂性将是O(nlogn),其是激光而不是O(n ^ 2)