Leetcode-509-斐波那契数

Leetcode-509-斐波那契数

题目描述

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

1
2
F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1

给你 n ,请计算 F(n)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
示例 1:

输入:2
输出:1
解释:F(2) = F(1) + F(0) = 1 + 0 = 1

示例 2:

输入:3
输出:2
解释:F(3) = F(2) + F(1) = 1 + 1 = 2

示例 3:

输入:4
输出:3
解释:F(4) = F(3) + F(2) = 2 + 1 = 3

思路一 : 动态规划

  • 斐波那契数的边界条件是 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)。

mark

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public int fib(int n) {
// 1. 特判
if(n < 2){
return n;
}
// 2.初始化变量
int dp_a = 0;
int dp_b = 0;
int dp_i = 1;
// 3. 滚动数组:动态规划
for(int i = 2;i <= n;i++){
dp_a = dp_b;
dp_b = dp_i;
dp_i = dp_a + dp_b;
}
return dp_i;
}
}

复杂度分析

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

思路二 : 数学通项

  • 斐波那契数 F(n)是齐次线性递推,根据递推方程 F(n)=F(n-1)+F(n-2)可以写出这样的特征方程:

mark

mark

1
2
3
4
5
6
7
class Solution {
public int fib(int n) {
double sqrt_5 = Math.sqrt(5);
double fib_n = Math.pow((1 + sqrt_5)/2,n) - Math.pow((1 - sqrt_5)/2,n);
return (int)Math.round(fib_n/sqrt_5);
}
}

复杂度分析

  • 与各个语言的pow 函数有关
打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2019-2022 Zhuuu
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信