【问题标题】:Why Time complexity of Fibonacci using for loop is O(n^2) and not O(n)?为什么使用 for 循环的斐波那契时间复杂度是 O(n^2) 而不是 O(n)?
【发布时间】:2018-12-13 14:25:36
【问题描述】:

为什么时间复杂度计算为 O(n^2) 而不是以下算法的 O(n)。

FibList(n)
    array[0-n] Create Array            O(n)
    F[0] <- 0                          O(1)
    F[1] <- 1                          O(1)

    for i from 2 to n                  O(n)
        F[i] <- F[i-1] + F[i-2]        O(n) 

    return F[n]                        O(1)

O(n) + O(1) + O(1) + O(n) O(n) + O(1) = O(n^2)

【问题讨论】:

  • F[i] &lt;- F[i-1] + F[i-2]O(1)
  • 现在创建一个大小为 n 的数组也是 O(1)。
  • @Adam 这是一个假设。使用不同的假设,即 F[i-1] + F[i-2] 成本 O(log_2(max(F[i-1], F[i-2]))) (即成本取决于位数),你得到O(n ^ 2)。看我的回答。

标签: algorithm time-complexity fibonacci


【解决方案1】:

如果您假设将具有k1 位的整数与具有k2 位的整数相加的成本与max(k1, k2) 成正比(这就是所谓的“位”成本模型,或“对数”成本模型),那么您生成的代码的时间复杂度为 O(n^2)。

这是因为 F(i) (几乎)与 phi^i 成正比,其中 phi 是黄金比例。这意味着 F(i) 有 ~i 位。

所以成本:

for i from 2 to n
    F[i] <- F[i-1] + F[i-2]

与 (1 + 2 + 3 + ... n-1) 成正比,即 n(n-1)/2,因此为 O(n^2)。

如果假设任意大小的整数相加是 O(1),那么代码就是 O(n)。

有关成本模型的背景,请参阅维基百科https://en.wikipedia.org/wiki/Analysis_of_algorithms#Cost_models 上的此部分

这里必须小心;例如,一些分析计算 将两个数字相加作为一个步骤。这个假设可能不 在某些情况下得到保证。例如,如果涉及的数字 一次计算可以任意大,单次所需的时间 不能再假定加法是恒定的。

顺便说一句,您的问题中使用的方法,即写出每行的最大复杂度,然后乘以嵌套的复杂度,并不是计算紧密绑定复杂度的有效方法,尽管它适用于所有复杂度都是多项式的情况,在这种情况下,它们是。

【讨论】:

  • 循环迭代次数和位数不相关。所以你永远不会得到n^2。也许 m*n。无论如何,找到最大值是 O(1),因为 int 位数很可能是 4 个字节。
  • @TonyTannous F[i] 有 ~i 位,i 是循环计数器,所以在这种情况下它们是相关的。
  • 可能 i 位超出 sizeof(int) 位正在使用。我不知道任何会花费 i 位而不是 sizeof(int) 的操作。
  • @TonyTannous 添加两个 bignums 怎么样?
  • 如果我错了,请纠正我,添加任何两个数字都会花费 sizeof(type)。
猜你喜欢
  • 2020-03-22
  • 1970-01-01
  • 1970-01-01
  • 2011-11-24
  • 1970-01-01
  • 2021-08-13
  • 1970-01-01
  • 2019-03-02
  • 2019-05-15
相关资源
最近更新 更多