【问题标题】:Python "in" operator time complexity on range()范围()上的Python“in”运算符时间复杂度
【发布时间】:2019-09-13 19:46:14
【问题描述】:

我有以下功能:

def foo(length, num):
  return num in range(length)

这个函数的时间复杂度是多少?注意到range()在Python 3上创建了一个Range对象,这个函数的时间复杂度是O(1)还是O(N)?

想知道各种 Python 版本之间的时间复杂度是否也存在差异(2 对 3)。

【问题讨论】:

  • 如果项目是int,那么在 Python-3.x 中将采用 O(1),而 O(n) 在 Python-2.x 中。对于floats,两者都是O(n)
  • 太棒了!您想回答这个问题吗?我可以将其标记为正确?
  • @geckos 这里不涉及任何生成器。
  • @geckos,当您从 range(...) 创建一个集合时,它已经是 O(n) 复杂度,因为 range(...) 的所有元素都将存储在内存中.

标签: python python-3.x algorithm python-2.7 range


【解决方案1】:

中,range(..) 是一个对象,它不构造列表。如果您使用int 作为项目执行成员检查,那么它可以非常快地做到这一点。该算法有点复杂,因为有积极和消极的步骤。您可以在[GitHub] 上查找。 x in range(a, b, c) 具有正步数 (c > 0) 的简单算法类似于:

x ≥ a ∧ x .

对于负步数 (c < 0) 非常相似:

x ≤ a ∧ x > b ∧ mod(x-a, c) = 0.

如果我们考虑在 O(1) 中进行比较并计算模数,则它是一个 O(1) 算法。实际上对于巨大的数字,它会根据数字的位数进行缩放,因此它是一个 O(log n) 算法。

但这仅适用于ints。事实上,如果您使用floats、complex、其他数字或非数字类型,它不会执行上述计算。然后它将退回到迭代 range(..) 对象。当然,这可能需要相当长的时间。如果你有一百万个元素的范围,它将遍历所有这些元素并最终到达范围的末尾,并返回False,或者找到一个匹配项,并返回True。将来,也许可以为某些数值类型实现一些额外的功能,但一般不能这样做,因为您可以使用不同的相等运算定义自己的数值类型。

中,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 该数字的值.

也有一个 xrange(..) 对象,但这不会使用上述演示的技巧检查成员资格。

【讨论】:

    猜你喜欢
    • 2013-08-10
    • 2016-05-13
    • 2012-12-02
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    相关资源
    最近更新 更多