我有两个阵列,一个现有的约会和一个潜在的约会。每个数组都包含现有或潜在约会的值/到值。每个数组中的约会已按时间排序。
我需要检查每个现有约会的每个潜在约会,看看没有重叠。我知道我可以从现有的约会开始每次,但我正在寻找一种更有效的方式。
答案 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
注意 - 如果您要查找所有重叠对,而不是在检测到第一次重叠后退出,则可以打印i
和j
并增加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_start
和A_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
中按结束时间维持降序来进一步优化它。然后,当打印a
和lastP
之间的所有重叠时,您可以在lastP
中潜在约会的结束时间小于{{的开始时间时停止查看1}}。
答案 3 :(得分:0)
如果我们首先加入这两个数组并且加入所需的时间是O(n)然后我们对整个数组进行排序,如果我们使用快速排序或合并排序,那么这个排序需要O(nlogn)然后我们计算总数时间的复杂性,就像这样
F(n)= O(n)+ O(nlogn)
因此最终的复杂性将是O(nlogn),其是激光而不是O(n ^ 2)