自下而上方法(DP)中斐波纳契数列的时间复杂度

时间:2016-09-18 01:41:18

标签: c++ algorithm time-complexity fibonacci

自下而上算法

a[0]=0,a[1]=1
integer fibo(n)
   if a[n]== null
       a[n] = fibo(n-1) + fibo(n-2)
   return a[n]

此算法的时间限制为O(N)

对于5,它会调用8次。 pass of fibnacci series in Bottom Up approach

fibo(5)调用8次从上到下,并调用8次从底部返回顶部。总呼叫是8 + 8 = 16我的观点。那么时间复杂度如何O(N)对我来说还不清楚。

我在这里找到了很多类似的问题,但所有这些问题都与我的问题无关 利益。 其中一些是:

Time Complexity of Fibonacci Series

Time Complexity of Fibonacci Algorithm

任何帮助都将不胜感激。谢谢

1 个答案:

答案 0 :(得分:2)

在回答有关时间复杂性的问题之前,有几件事要提及。原因是时间复杂性至少部分取决于这些答案。

首先,你的程序中似乎有一个错误,因为你有一个数组' a'对于基本条件(Fibbinacci数字0和1)和一些数组' m'这是在fibo函数中设置的,但从未再次使用过。更重要的是,当你达到n = 1或n = 0时,你返回m [n]的值,这是完全未知的。所以,我将假设算法被重写如下:

a[0]=0,a[1]=1
integer fibo(n)
   if a[n]== null
       a[n] = fibo(n-1) + fibo(n-2)
   return a[n]

好的,第二个问题。让我们假设a总是被定义为至少n + 1个整数。需要有足够的空间容纳传入的数据。这很重要,因为c ++会让你覆盖n + 1 th 索引的值。它出了界限和错误,但是c ++并没有提供那种保护。作为程序员,您需要验证这样的边界条件。 (我假设使用c ++,因为这是用c ++标记的。代码看起来更像是python,它的环绕索引本身就有问题。)

第三,我们假设您没有开始使用新阵列' a'对于算法的每次运行。这很重要,因为如果存储已经计算的值,那么您将不必重新评估这些值,从而节省计算时间。即使它不会影响我计算时间复杂度的方式,节省时间也是一件好事。

大。让我们开始讨论您的问题。让我们使用下面的图片来回答它。当您在n处启动算法时,您将对fibo(n-1)和fibo(n-2)进行两次递归调用,但它们不会同时发生。相反,第一次调用fibo(n-1)发生,并且必须在第二次调用fibo(n-2)之前100%完成。该调用由n th 线上的n-1到n-1 th 线的绿线表示。

现在,这些绿线适用于每行的递归,直到你到达fibo(1)调用。该调用会提前终止,因为[n]不为空。最后执行第二次对fibo(0)的调用,它也会提前终止,因为[n]不为空。好的,第一组递归调用非常多。

当每个递归调用返回时,进行第二次调用(由橙色虚线表示),但是[n]不再为null,因此调用会提前终止,并且调用将返回到下一层。

所以,让我们计算通话次数。从n到1是n-1个递归调用。最后还有一个对fibo(0)的额外调用,因此这是n个递归调用。然后在前进的路上有n-2个额外的呼叫,提前终止。所以,我们总共有2n-2个调用,即O(n)。

enter image description here

当然,如果你调用fibo(k)然后调用fibo(k + x),你只需要进行前2次调用,因为从fibo(k)向下的所有内容都是已知的。在初始投资之后,这是相当可观的节省。有问题吗?

关于O(2n)= O(n),这是一个很好的跟进。 Big-O复杂性规则表明,当您比较效率时,我们对数量级感兴趣。所以,假设你在看n = 1000。 O(n)= 1000,O(2n)= 2000,但O(n 2 )= 1,000,000。 O(n)或多或少与O(2n)相同,但如果将它们与O(n 2 )进行比较,则这是一个巨大的差异。同样,如果你有O(n + 1)= 1001与O(n)有很大的不同。所以,一般来说,我们说主导词,等式中最重要的值是重要的。我们对额外的条款并不感兴趣。我们对特定系数并不感兴趣,因为它们并不会真正影响结果。

如果您仍有疑问,请访问此网站以获取更多信息。 https://justin.abrah.ms/computer-science/big-o-notation-explained.html