我具有以下功能:
def foo(length, num):
return num in range(length)
此功能的时间复杂度是多少?注意到range()
在Python 3上创建了Range对象,该函数的时间复杂度是O(1)还是O(N)?
想知道各种Python版本之间的时间复杂度是否也有所不同(2 vs 3)。
答案 0 :(得分:3)
在python-3.x中,range(..)
是一个对象,它不构造列表。如果执行成员检查并以int
作为项目,则可以很快完成。该算法有点复杂,因为存在正向和负向步骤。您可以在[GitHub]上查找它。对于 c > 0
,一个具有正步数(x in range(a, b, c)
)的简单算法类似于:
x≥a∧x 。
对于负步数(c < 0
)非常相似:
x≤a∧x> b∧mod(x-a,c)= 0 。
如果我们认为要在 O(1)中进行比较并计算模数,则它是 O(1)算法。实际上,对于庞大的数字,它会按数字的位数进行缩放,因此它是一种 O(log n)算法。
这仅适用于int
秒。的确,如果您使用float
,complex
,其他数字或非数字类型,它将不会执行上述计算。然后它将遍历range(..)
对象。当然哪个会花费大量时间。如果您拥有一百万个元素的范围,它将对所有这些元素进行迭代并最终到达范围的末尾,并返回False
,或找到一个匹配项,然后返回True
。将来,也许可以为某些数字类型实现一些额外的功能,但是通常不能这样做,因为您可以使用工作原理不同的等式运算来定义自己的数字类型。
在python-2.x中,range(..)
是一个返回列表的函数。确实:
>>> range(15)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
>>> type(range(15))
<type 'list'>
为了检查元素是否为列表的成员,它将在列表上进行迭代,并检查所有项目的相等性,直到找到相等的元素或列表用尽。如果我们考虑检查两个项目是否等于恒定时间,则这需要线性时间 O(n)。实际上,对于巨大的数字,请检查两个数字是否相等,并与“位数”成线性比例,因此 O(log m)与 m 等于该数字的值
python-2.x也有一个xrange(..)
对象,但这并不能通过上述技巧来检查成员资格。