例如:我们有一个列表:
1 2 3 7 8 9 11 12
我们需要检查范围 (A,B) 是否与列表重叠,例如范围 (4, 6) 与列表不重叠,范围 (10, 12) 和范围(5,9) 与列表重叠。我知道我们可以将列表放入 hashSet 中,然后我们只需检查范围内的任何元素是否出现在该集合中。这需要 O(N)。N 是范围的长度。有没有更好的算法来解决这个问题?我知道有一个区间树数据结构,但我不太明白。该结构可以在 logN 中解决这个问题吗?
例如:我们有一个列表:
1 2 3 7 8 9 11 12
我们需要检查范围 (A,B) 是否与列表重叠,例如范围 (4, 6) 与列表不重叠,范围 (10, 12) 和范围(5,9) 与列表重叠。我知道我们可以将列表放入 hashSet 中,然后我们只需检查范围内的任何元素是否出现在该集合中。这需要 O(N)。N 是范围的长度。有没有更好的算法来解决这个问题?我知道有一个区间树数据结构,但我不太明白。该结构可以在 logN 中解决这个问题吗?
似乎列表已排序;如果还没有,请先对其进行排序。
让R = (start, end)
我们要检查它是否重叠的范围。
我们可以对排序列表的位置start
进行二分搜索:end
start
和end
连续出现在列表中,那么它们不会重叠例如
1 2 3 4 6 7 8 9 11 12
看:
1 2 3 7 8 9 10 11 12
这是O(log N)
,其中N
是列表中元素的数量。
如果列表未排序:
O(M) 其中 M 是列表中的项目 # 是遍历列表检查每个项目以查看是否低 <= 项目 <= 高。
如果域是“合理”有界的,则另一种选择:
将列表表示为位向量。将范围表示为位向量(此向量中的 on 位将是连续的)然后“和”向量以查看是否有共同的位。
如果列表已排序,您可以找到范围中的最小元素将被放置到列表中的位置,以及范围中最大的元素将被放置到列表中的位置。这将花费 2 lg(n) 时间。如果这些索引不同,则范围与列表相交。否则,我不知道。
显然,如果列表没有排序,那么任何为范围查询构建 ad hoc 结构的算法都将花费 O(n)。对列表进行排序将花费 O(n log n)。
使用集合(实现为平衡二叉树),将通过插入范围的下(或上)边界并检查下一个(或上一个)元素(数据结构)以 O(log 2 n) 输出结果必须支持该操作,这在二叉树上是微不足道的)。
一个非常有效的范围查询结构是B+tree,它可以让您在 O(log b n+k) 中找到一个范围,其中 b 是树的等级(即每个节点的子节点数)。请注意,这还将返回范围内的元素列表(例如,作为树数据集上的几个迭代器)。
另一个有趣的结构是Van Emde Boas树,它在 O(log log n) 中插入元素。使用与上述集合相同的技巧,我们可以找到具有相同时间复杂度的答案。另请参阅 X 快速尝试和 Y 快速尝试。
我知道您只想知道数组中是否存在 A 或 B。您无需使用排序,因为您只需执行 2 个步骤:
1- search that is there A or B in your array.(you can do it in O(n))
2- find minimum and maximum.(you can do it in o(n)).
您可以在 o(n) 内完全完成,并且您不能在小于 o(n) 的时间内完成,我在此链接中针对相同的问题对此进行了检查。