Swift - LeetCode - 斐波那契数

279 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第25天,点击查看活动详情

题目

斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列。该数列由 01 开始,后面的每一项数字都是前面两项数字的和。也就是:

F(0) = 0F(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(0)=0F(1)=1。当 n>1 时,每一项的和都等于前两项的和,因此我们可以知道有如下递推关系:

F(n)=F(n-1)+F(n-2)

由于斐波那契数存在递推关系,因此我们可以使用动态规划求解。动态规划的状态转移方程即为上述递推关系,边界条件为 F(0)F(1)

我们根据状态转移方程和边界条件,可以得到时间复杂度和空间复杂度都是 O(n) 的实现。由于 F(n) 只和 F(n-1)F(n-2) 有关,因此可以使用「滚动数组思想」把空间复杂度优化成 O(1)。如下的代码中给出的就是这种实现

代码

class Solution {
    func fib(_ n: Int) -> Int {
        if n < 2 {
            return n
        }
        
        var p: Int = 0
        var q: Int = 0
        var r: Int = 1
        for _ : Int in 2...n {
            p = q
            q = r
            r = p + q
        }
        return r
    }
}

复杂度分析

  • 时间复杂度:O(n)。

  • 空间复杂度:O(1)。