【发布时间】:2018-12-31 18:05:10
【问题描述】:
假设区间列表可能是 [[1,3],[2,4],[6,12]] 并且查询时间 T = 3。上面列表中为 3 的区间数为 2 (即) [[1,3],[2,4]]。是否有可能在 O(logn) 时间内做到这一点?
【问题讨论】:
-
有时间限制吗?
标签: algorithm binary-search interval-tree
假设区间列表可能是 [[1,3],[2,4],[6,12]] 并且查询时间 T = 3。上面列表中为 3 的区间数为 2 (即) [[1,3],[2,4]]。是否有可能在 O(logn) 时间内做到这一点?
【问题讨论】:
标签: algorithm binary-search interval-tree
在一般情况下,这不能在 O(log n) 时间内完成。
您可以对开始时间进行二分搜索以查找可能包含查询时间的最后一个间隔,但由于结束时间没有隐含的顺序,您可以从列表的开头顺序搜索到您确定的项目作为最后一个确定查询时间是否在任何这些时间间隔内。
例如,[(1,7),(2,11),(3,8),(4,5),(6,10),(7,9)],查询时间为 7。
开始时间的二分搜索会告诉你所有的时间间隔可能包含查询时间。但是因为结束时间没有任何特定的顺序,所以你不能对它们进行二分搜索。您必须查看每个单独的时间间隔以确定结束时间是否大于或等于查询时间。在这里,您看到(4,5) 不包含查询时间。
【讨论】:
嗯,需要注意的一点是,对于包含 T 的区间,它的开始时间必须小于或等于 T。由于这些是按开始时间排序的,因此您可以使用基本的二分搜索来消除所有的在 O(log n) 时间内开始太晚了。
如果我们可以假设这些也按结束时间排序——也就是说,没有一个区间完全包含前一个区间——那么你可以使用另一个二分搜索来消除所有结束时间在 T 之前的区间。那将将运行时间保持在 O(log n)。
如果我们不能做出这样的假设,事情会变得更加复杂,我想不出任何比 O(n log n) 更好的方法 [通过按结束时间对剩余列表进行排序并执行另一次二分搜索在那]。或许有办法?
EDIT 正如 Qbyte 下面所说,最后的排序是多余的;您可以通过对剩余集合进行简单的线性搜索将其降低到 O(n)。话又说回来,如果您仍然使用 O(n) 解决方案,您不妨跳过整个算法,只对原始集合进行线性搜索。
【讨论】:
让我们假设间隔按开始时间排序。二分查找 O(log n) 将消除不能包含 T 的区间。剩下的可能。
你必须扫描剩下的,O(n),数一数。总复杂度 O(n)。鉴于此,您还不如从未进行二分搜索而只扫描整个列表。
如果其余的也按结束时间排序,您可以再进行一次二分查找,将复杂度保持在 O(log n)。
但你还没有完成。你需要计数。
你知道开始的计数。如果你不这样做,你就不能进行二进制搜索。您将知道每个二进制搜索的最后测试的索引。从这里开始,这是一个 O(1) 计算选项。
因此,此选项的总复杂度为 O(log n)。
【讨论】: