【问题标题】:How can we find the Time Complexity of the Algorithm我们如何找到算法的时间复杂度
【发布时间】:2021-07-08 14:25:55
【问题描述】:

我想知道下面给定代码的时间复杂度,我怀疑它是根 n 的 O

i = n, sum = 0
while (i >= 0){
    i /= 2
    sum += i*i*i
}

我真的很困惑,谁能帮我解释一下

【问题讨论】:

  • 这个算法返回一个无限循环。这个答案可以帮助您理解为什么计算它的时间复杂度没有意义。 stackoverflow.com/questions/7733397/…
  • 是的,我知道,但是在我们的 mcq 中,由于无限,我们没有可以选择的任何东西
  • @FeioNedio 对于 O(logn) 时间算法,条件可能是 i > 0 而不是 >=

标签: algorithm


【解决方案1】:

如果您不确定,您可以随时使用“时间”模块大致了解复杂性。它会是这样的。

进口时间

start = time.time() # 放在循环之前

end = time.time() #把这个放在循环之后

print(end - start) #this 为您提供循环的评估时间

找出不同 n 的评估时间并确定复杂度。

只是通过查看它,您的循环大约会执行 log2(n) 次,并且在内部您有 2 次乘法和 1 次除法(所以没什么复杂的)。因此,我认为 O(log(n)) 是一个合理的猜测。

【讨论】:

  • 嗯,原则上是的。但是,在实践中,您不会想要测量无穷大(或非常弱收敛的实现所花费的时间)。语言的类型可能会提供不精确性,但对于一些新的想法可能会访问一些阿基里斯悖论的展示,它很好地展示了将数字减半到零的问题...... Achilles and the Tortoise 有一个链接到 a formulation from Zeno of Elea
  • 我不同意这个答案。运行时间为 O(log n) 的函数的运行时图看起来或多或少像一个常数,因为 log n 增长如此缓慢。在这种特殊情况下,该函数是如此之短,以至于很难准确地测量它花费在计算上的时间,而且你大部分会留下一条平坦的线,那里有一堆噪音。虽然这是让自己相信函数的实际速度足够好的好方法,但还不足以确定实际增长率。​​span>
  • @templatetypedef 好吧,在这种情况下测试运行时没有用,这是一个好点。但我仍然是正确的,它是 O(log n)。
【解决方案2】:

正如 cmets 中提到的,我假设代码应该写成

i = n, sum = 0
while (i > 0) { // <--- Change >= to >
    i /= 2
    sum += i*i*i
}

否则代码将是一个无限循环。考虑到这一点,让我们看看这段代码在做什么。

对于初学者,请注意sum 变量没有做任何影响我们时间复杂度的事情。在每次迭代中,它都会变大,但我们只做 O(1) 的工作来更新它。这意味着这里的时间复杂度将取决于循环运行的次数。请注意,在循环的不同迭代中,i 的值将采用序列

n, n / 2, n / 4, n / 8, n / 16, n / 32, ...

特别是,在循环的第 k 次迭代中,i 的值将等于 n / 2k(忽略向下舍入,我们可以在这里安全地执行此操作)。那么,问题是在循环的哪一次迭代中,我们以 n / 2k

n / 2k

n k

log2 n

所以一旦循环迭代次数 k 大于 log2 n,这个循环就会停止。这意味着我们做了 Θ(log n) 循环迭代,其中每次迭代做 O(1) 工作,所以完成的总工作是 Θ(log n)

【讨论】:

    猜你喜欢
    • 2012-06-17
    • 1970-01-01
    • 2020-10-27
    • 2019-03-26
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    相关资源
    最近更新 更多