为什么用这两种算法找到第n个斐波那契数的效率更高?

时间:2019-04-21 03:24:10

标签: python algorithm fibonacci

计算第64个斐波纳契数时,第一个算法需要花费几个小时,而第二个算法则需要不到一秒钟。

为什么第二种算法的效率比第一种算法高得多?

它们看起来非常相似。

def fib_divide_recursion(n):
    if n <= 2:
        return n-1
    else:
        return fib_divide_recursion(n-1) + fib_divide_recursion(n-2)

def fib_linear_recursion(n, prev={}):
    if n <= 2:
        return n-1
    try:
        return prev[n]
    except KeyError:
        prev[n] = fib_linear_recursion(n - 1, prev) + 
            fib_linear_recursion(n - 2, prev)
        return prev[n]

3 个答案:

答案 0 :(得分:3)

第二种实现方式是使用“记忆”来记住先前计算的斐波那契值。

请考虑您要计算fib(5):首先必须计算fib(4)fib(3)fib(4)本身也需要您计算fib(3)。实际上,对于每个斐波那契数字,您可以一次计算每个前面的斐波那契数字并将其存储(这是记忆方法)。或者,以较差的性能,即使您之前已经计算过,也可以重新计算所需的每个斐波那契数。显然,没有记忆,您将需要做成倍的工作,而且对于高斐波那契数,这确实有所作为。

答案 1 :(得分:1)

第一个算法的复杂度为O(2 ^ n)。

第二个将结果缓存在prev中,因此对于给定的数字,它永远不会多次计算fib_linear_recursion。它的复杂度是线性的O(n)。

有关更多详细信息,请参见this answer

答案 2 :(得分:1)

第一种算法仅使用递归,而第二种算法使用动态编程,即带备忘录的递归。

如果您为第一算法绘制树,则会看到重复的节点。但是使用第二种算法,它将存储已经计算出的节点,因此程序不必一次又一次地为此计算