【问题标题】:Dynamic range search [duplicate]动态范围搜索 [重复]
【发布时间】:2012-01-05 22:48:18
【问题描述】:

可能重复:
Fast Algorithm to Quickly Find the Range a Number Belongs to in a Set of Ranges?

给定一个不重叠且已排序的数字范围列表(rangeList)和一个数字,编写一个有效的算法首先查找该数字是否存在于(某个范围内)rangeList中,如果确实存在,则返回正确的范围。

例如 rangeList = [(-1, 200), (300, 2000), (2011, 2300)]

查询 1: 1000 -> (True, (300, 2000) ) 因为 1000 介于 300 和 2000 之间。

查询 2: 250 -> (False, (None, None) ) 因为没有 250 在列表的任何范围内都不存在。

我想出的最佳算法是使用二分搜索 log N。这感觉像是一个非常常见的问题,尤其是对于基于经度/纬度的搜索。有什么想法可以使它比 log N 更好吗?

【问题讨论】:

  • 好问题。我想不出任何不涉及硬编码哈希函数的更好方法。
  • 谢谢。你能详细说明硬编码的哈希吗?你是说记忆吗?
  • 有点。我会发布答案...
  • 当然,我只是在发布我的答案后才看到。 xD 好吧,无论如何,我会留给您阅读,同时我会检查其他问题...

标签: algorithm data-structures computer-science


【解决方案1】:

我不确定这是否能达到你想要的效果,但这是一次尝试。它将涉及一个 O(n) 的预处理步骤,作为回报,它将为任何给定的查询提供 O(1) 运行时的机会,以平衡空间复杂度(通过参数 c)。如果您的 rangeList 经常更改,这可能不会有帮助。

预处理步骤:

  1. 查找范围列表的“总范围”(可接受的最低值和最高值,尽管两者之间会有差距)。 O(1)

  2. 选择浓度参数 c(整数),表示您希望在该范围内评估多少点。 O(1)

  3. 创建一个映射函数,将整数 [1, c] 映射到步骤 1 中找到的总范围,并且还可以进行逆运算(这并不比摄氏-华氏转换复杂)。也是 O(1)

  4. 使用映射函数,确定总范围内与 [1, c] 对应的点。扫描范围列表,随时评估这些点,将答案( (True, (300, 2000)) 等)存储在长度为 c 的数组中(我们将数组称为“已评估”)。 O(n + c)

收到查询后:

  1. 使用映射函数在“总范围”->[1,c]方向转换查询数。如果转换后的数字超出范围 [1, c],则返回 (False, None, None)。 O(1)

  2. 取转换后数字的上限和下限,这将为您提供两个整数 a 和 b。比较 Evaluated[a] 和 Evaluated[b]。如果它们包含相同的答案,则返回它(如果转换后的数字已经是整数,则直接返回 Evaluated[converted number])。 O(1)

  3. 如果 Evaluated[a] 和 Evaluated[b] 给出不同的答案,则必须进行二分搜索。但您至少可以在 a 和 b 之间的中间位置开始搜索,映射回“总范围”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多