斐波那契数列的几种实现方法

141 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第18天,点击查看活动详情

我正在参加 码上掘金体验活动,详情:show出你的创意代码块

前言

对于斐波那契数列,可能大家都不陌生,今天一个朋友问我关于斐波那契数列的实现有几种方法,以及其时间空间复杂度。今天我们就来讨论讨论这个吧。

定义

按照惯例,先来看看它的定义。

斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从 1963 年起出版了以《斐波纳契数列季刊》为名的一份数学杂志,用于专门刊载这方面的研究成果。——百度百科

递归实现

function fib(n){
    if(n <= 0) return 0
    if(n === 1) return 1
    return fib(n-1) + fib(n-2)
}
console.log(fib(0)); // 0
console.log(fib(2)); // 1
console.log(fib(1)); // 1
console.log(fib(5)); // 5

时间复杂度O(2^n),空间复杂度O(n)

优化1

由于数组的特殊性,这里采用数组结构来进行优化

function fib(n) {
    let arr = [0,1] 
    for(let i = 2;i < n+1;i++){
        arr.push((arr[i-1]+arr[i-2]))
    } 
    return arr[n] 
};
console.log(fib(0)); // 0
console.log(fib(2)); // 1
console.log(fib(1)); // 1
console.log(fib(5)); // 5

时间复杂度O(n),空间复杂度O(n)

优化2

动态规划

function fib(n) {
    if(n <= 0) return 0
    if(n === 1) return 1
    let p = q = 0, r = 1 
    for(let i = 2;i <= n;i++){ 
        p = q 
        q = r 
        r = p+q
    }
    return r
};
console.log(fib(0)); // 0
console.log(fib(2)); // 1
console.log(fib(1)); // 1
console.log(fib(5)); // 5

时间复杂度O(n),空间复杂度O(1)

总结

动态规划用时 image.png

数组优化用时 image.png

递归用时 image.png 从上对比,可以看出递归是最费时的。这还是数据比较小的情况下,如果数据量比较大,比如1000000的情况下,递归可能会造成浏览器直接卡死或者会等很久的情况。因此,对于这种情况,我们应该尽可能的去优化,避免程序崩溃。