使用三元搜索查找范围内的所有元素?

时间:2012-11-22 07:32:16

标签: python algorithm search

我正在寻找平均案例性能为O(log(N))的算法,从排序列表中提取元素在(或等于)min和max值之间。

问题在于,由于最小值和最大值实际上可能不在列表中,或者甚至可能重复,因此二进制搜索不会这样做。三元搜索似乎更接近我所寻求的东西,但到目前为止,我还没有能够创建一个基于三元搜索的功能。

例如,输入:

list=[1,2,3,4,5,6,7], min=3, max=6

应该返回[3,4,5,6]。同样,

list=[500,757,2412,10000,123123], min = 600, max = 5000

应该返回[757,2412]。

这也可以使用以下方法在python中完成:

def withinRange(values,min,max):
   return [val for val in sorted(values) if val <= max and val >= min]

调用该操作足以使O(log(N))成为首选,并且排序只进行一次。

1 个答案:

答案 0 :(得分:2)

这似乎有效:

>>> import bisect
>>> def bin_slice(L, min, max):
...     i = bisect.bisect_left(L, min)
...     j = bisect.bisect(L, max)
...     return L[i:j]
... 
>>> bin_slice([1,2,3,4,5,6,7,8,9], 3, 6)
[3, 4, 5, 6]
>>> bin_slice([500,757,2412,10000,123123], 600, 5000)
[757, 2412]

复杂度类似于2log(N),即O(log(N))。还要注意bisect可以使用bisect的C实现,这比你在pure-python中编写的任何东西都要快,所以即使进行较少的比较,纯python解决方案可能会更慢

您可以略微优化j的搜索,将lo参数传递给bisect

j = bisect.bisect(L, max, i)