AlgoMooc
你已开通华为OD训练营权益,还差最后一步——完成入营激活(兑换课程 + 加飞书 + 登记服务群),即可解锁全部课程与专属服务。去激活 →
← OD 20 天课程

华为 OD 训练营 · 题解精讲

LC509. 斐波那契数

LC509. 斐波那契数

题目描述

斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是: F(0) = 0,F(1) = 1 F(n) = F(n - 1) + F(n - 2),其中 n > 1 给定 n ,请计算 F(n) 。 示例 1: 输入:n = 2 输出:1 解释:F(2) = F(1) + F(0) = 1 + 0 = 1 示例 2: 输入:n = 3 输出:2 解释:F(3) = F(2) + F(1) = 1 + 1 = 2 示例 3: 输入:n = 4 输出:3 解释:F(4) = F(3) + F(2) = 2 + 1 = 3 提示: 0 <= n <= 30

题目解析

解题思路

本题是经典的斐波那契数列计算,参考代码给出了三种实现方式:纯递归记忆化搜索动态规划。题目要求计算 F(n),核心是利用递推关系 F(n) = F(n-1) + F(n-2)

  • 纯递归:直接按定义递归,但存在大量重复计算,时间复杂度为指数级。
  • 记忆化搜索:在递归基础上引入 memo 数组缓存已计算过的子问题结果,避免重复递归,将复杂度降为 O(n)。
  • 动态规划:自底向上迭代,用 dp 数组记录每一步结果,无需递归调用,效率最高。

参考代码中实际执行的是动态规划版本myFib3),它用一个长度为 N+1 的数组 dp 存储从 0 到 N 的所有斐波那契数,然后通过循环依次计算。

关键步骤

1. 边界处理:若 N < 2,直接返回 N(即 F(0)=0, F(1)=1)。 2. 初始化 dp 数组dp[0] = 0dp[1] = 1。 3. 迭代计算:从 i = 2N,执行 dp[i] = dp[i-1] + dp[i-2]。 4. 返回结果dp[N] 即为所求。

迭代过程示意(以 N=4 为例):


dp[0]=0, dp[1]=1
i=2: dp[2] = dp[1]+dp[0] = 1+0 = 1
i=3: dp[3] = dp[2]+dp[1] = 1+1 = 2
i=4: dp[4] = dp[3]+dp[2] = 2+1 = 3

复杂度分析

  • 时间复杂度:O(n),只需一次循环计算 n-1 次加法。
  • 空间复杂度:O(n),用于存储长度为 n+1 的 dp 数组。若进一步优化,可只用两个变量滚动更新,将空间降至 O(1),但参考代码未采用此优化。

参考代码

class Solution:
    def __init__(self):
        self.times1 = 0

    def fib(self, N):
        self.times1 = 0
        result = self.myFib1(N)
        print(self.times1)
        return result

    def myFib1(self, N):
        self.times1 += 1

        if N == 0:
            return 0

        if N == 1:
            return 1

        return self.myFib1(N - 1) + self.myFib1(N - 2)

# 记忆化搜索
class Solution:
    def __init__(self):
        self.times1 = 0
        self.memo = None

    def fib(self, N):
        self.times1 = 0
        self.memo = [-1] * (N + 1)
        result = self.myFib2(N)
        print("myFib2 调用的次数为: ", self.times1)
        return result

    def myFib2(self, N):
        self.times1 += 1

        if N == 0:
            return 0

        if N == 1:
            return 1

        if self.memo[N] == -1:
            self.memo[N] = self.myFib2(N - 1) + self.myFib2(N - 2)

        return self.memo[N]

# 动态规划
class Solution:
    def __init__(self):
        self.times1 = 0
        self.memo = None

    def fib(self, N):
        self.times1 = 0
        self.memo = [-1] * (N + 1)
        result = self.myFib3(N)
        print("myFib3 调用的次数为: ", self.times1)
        return result

    def myFib3(self, N):
        if N < 2:
            return N

        dp = [-1] * (N + 1)
        dp[0] = 0
        dp[1] = 1

        for i in range(2, N + 1):
            dp[i] = dp[i - 1] + dp[i - 2]

        return dp[N]