动态范围搜索

时间:2011-11-24 21:22:16

标签: algorithm data-structures computer-science

  

可能重复:
  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.这感觉像是一个非常常见的问题,特别是对于基于经度/纬度的搜索。是否有任何想法使这比记录N更好?

1 个答案:

答案 0 :(得分:1)

我不确定这会实现你想要的,但这是一个机会。它将涉及O(n)预处理步骤,并且反过来将在O(1)运行时为任何给定查询提供与空间复杂度平衡的机会(通过参数c)。如果您的rangeList经常更改,这可能没有帮助。

预处理步骤:

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

  2. 选择一个浓度参数c(整数),表示您要在该范围内评估的点数。 O(1)

  3. 创建一个映射函数,将整数[1,c]映射到步骤1中找到的总范围,也可以反转(这不比Celsius-Farenheit转换复杂)。也是O(1)

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

  5. 收到查询后:

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

    2. 取转换后的数字的天花板和地板,这将给出两个整数a和b。比较评估[a]和评估[b]。如果它们包含相同的答案,则返回它(如果转换的数字已经是整数,则直接返回Evaluated [转换后的数字])。 O(1)

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