博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
DP 斐波那契数列js NC68
阅读量:4130 次
发布时间:2019-05-25

本文共 1186 字,大约阅读时间需要 3 分钟。

斐波那契数

指的是这样一个数列:0、1、1、2、3、5、8、13、21、…… 

用数学公式表示为:

简单的来说就是 后一项是前两项之和

 

方法一:递归

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

// 递归法function Fibonacci(n) {    if (n < 2) {        return n;    } else {        return Fibonacci(n - 1) + Fibonacci(n - 2);    }}

由于是递归调用,每次调用F函数的时候,会导致F(n)重复计算。因为,每个值最终被拆解为 F(1)+F(0).

正如上图,F(5)= F(1)+F(0)+F(1)+F(0)+F(1)+F(1)+F(0)+F(1) = 8

 

方法二:尾递归

时间复杂度为O(n)

定义:当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归。

简单理解,就是处于函数尾部的递归调用本身的情形下,前面的变量状态都不需要再保存了,可以释放,从而节省很大的内存空间。

递归和尾递归写法的区别

return f(n-1)+f(n-2)  //递归

return f(n-1,...)  //尾递归

//尾递归 不爆栈function Fibonacci(n, a, b) {    if (n <= 1) {        return a;    }    return Fibonacci(n-1, b, a+b)    //每次的b就是要求当前的返回值,当执行到b减到0的时候,此时的b就是我们要求的第n个数}

尾递归的调用:F(5,1,1)=F(4,1,2)=F(3,2,3)=F(2,3,5)=F(1,5,8)=F(0,8,13)

  所以,当我们调用F(5,1,1)的时候相当于变相的调用了F(0,8,13),正如上文中所说 :当编译器检测到一个函数调用是尾递归的时候,它就覆盖当前的活动记录而不是在栈中去创建一个新的。 因为后续的方法并不依赖于之前的方法。

 

方法三:迭代(使用变量)

使用三个变量存储可以节省内存,但缺点是只能保存最后计算的值以及前两个值,以前的值会被替换掉。

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

//动态规划function Fibonacci2(n) {    if (n <= 1) {        return n;    }    var n1 = 0, n2 = 1, sum;    for (var i = 2; i < n; i++) {        sum = n1 + n2        n1 = n2        n2 = sum    }    return sum}

 

斐波那契数列的应用题:青蛙跳台阶问题、变态跳台阶、矩形覆盖

转载地址:http://onuvi.baihongyu.com/

你可能感兴趣的文章
外存IO操作
查看>>
如何开发一个程序
查看>>
python初学
查看>>
实体消歧,实体识别,实体融合,知识融合概述
查看>>
Linux使用
查看>>
scala初学
查看>>
Majority Element
查看>>
LeetCode感想
查看>>
Contains Duplicate
查看>>
Missing Number
查看>>
Third Maximum Number
查看>>
Find All Numbers Disappeared in an Array(哈希表)
查看>>
Add Binary
查看>>
(a+b)/2与a+(b-a)/2的区别
查看>>
LeetCode之Math
查看>>
Isomorphic Strings
查看>>
刷题过程中的API新解
查看>>
LeetCode过程中遇到的代码错误
查看>>
关于Java对象引用的理解
查看>>
Java二维数组访问的行优先问题
查看>>