1. 概述

在本篇文章中,我们将对比三种常见的斐波那契数列计算方式:

  • 递归方法(Recursive)
  • 自顶向下动态规划(Top-Down DP)
  • 自底向上动态规划(Bottom-Up DP)

这三种方式在时间复杂度、空间复杂度以及实现思路上各有特点,适用于不同场景。理解它们之间的差异,有助于我们更好地掌握动态规划的核心思想。


2. 斐波那契数列简介

斐波那契数列是一个经典的递归定义数列,其定义如下:

F(0) = 0, F(1) = 1, F(N) = F(N-1) + F(N-2)

换句话说,从第3项开始,每一项都等于前两项之和:

0, 1, 1, 2, 3, 5, 8, 13, 21, ...

我们重点讨论如何高效地计算第 N 项。


3. 不同实现方式对比

3.1. 递归实现(Recursive Approach)

这是最直观的实现方式,直接根据定义递归调用:

algorithm RecursiveFibonacci(N):
    if N = 0 or N = 1:
        return N
    return RecursiveFibonacci(N - 1) + RecursiveFibonacci(N - 2)

优点:代码简单,逻辑清晰
缺点:存在大量重复计算,时间复杂度为 **O(Φ^N)**,效率极低

⚠️ 踩坑提醒:当 N > 30 时,递归方式已经开始变得不可接受,当 N 达到 40 或更高时,执行时间会明显变慢。

下图展示了递归过程中重复计算的子问题树:

Fibonacci top down


3.2. 自顶向下动态规划(Top-Down DP)

也叫记忆化递归(Memoization),通过缓存中间结果避免重复计算。

algorithm TopDownFibonacciHelper(N):
    Array <- an array of size N + 1 initialized to 0
    return TopDownFibonacci(N, Array)

主函数如下:

algorithm TopDownFibonacci(N, Array):
    if N = 0 or N = 1:
        return N

    if Array[N] != 0:
        return Array[N]

    Array[N] <- TopDownFibonacci(N - 1, Array) + TopDownFibonacci(N - 2, Array)

    return Array[N]

优点:保留递归结构,逻辑清晰;时间复杂度降为 O(N)
缺点:需要额外空间存储中间结果,空间复杂度为 O(N)

下图展示了加入记忆化后子问题树的变化:

Fibonacci memoization


3.3. 自底向上动态规划(Bottom-Up DP)

采用迭代方式,从最基础的子问题开始向上构建最终解。

algorithm BottomUpFibonacci(N):
    if N = 0 or N = 1:
        return N

    A <- 0
    B <- 1

    for I <- 2 to N:
        Temp <- A + B
        A <- B
        B <- Temp

    return B

优点

  • 时间复杂度为 O(N)
  • 空间复杂度优化为 **O(1)**,仅需两个变量存储中间结果

下图展示了从 F(0) 到 F(N) 的构建过程:

Fibonacci bottom up 1


4. 性能对比分析

实现方式 时间复杂度 空间复杂度 是否推荐
递归(Recursive) O(Φ^N) O(N)(调用栈)
自顶向下 DP(Top-Down) O(N) O(N)
自底向上 DP(Bottom-Up) O(N) O(1) ✅✅

⚠️ 踩坑提醒:在实际开发中,除非有特定需求(如需要保留递归结构),否则尽量避免使用纯递归实现斐波那契。

下图展示了递归方式与动态规划方式在时间复杂度上的巨大差异:

download-2


5. 总结

本文我们对比了三种常见的斐波那契数列实现方式:

  • 递归方法:直观但效率极低,不适用于实际项目
  • 自顶向下动态规划:保留递归结构,加入缓存优化,适用于中等规模问题
  • 自底向上动态规划:效率高,空间占用小,推荐作为首选实现方式

掌握这三种方式及其性能差异,有助于我们更好地理解动态规划的思想,并在实际开发中做出合理选择。


原始标题:Fibonacci: Top-Down vs Bottom-Up Dynamic Programming