【js算法】js斐波那契数列的多种算法

斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……从数列可以看出,从第三项开始,每一项都是前两项的和,f(n) = f(n-1) + f(n-2)
那么用js怎么求斐波那契数列第n项的值呢?

1.普通递归计算:

function fibonacci(n){
    if(n == 1||n == 2) return 1
    return fibonacci(n - 1) + fibonacci(n - 2)
}
fibonacci(5)
// > 5
fibonacci(50)
// >       卡住了

当n等于1或者n等于2的时候,直接返回1,当n大于2的时候,就递归函数,每次返回前两个函数的结果,这就是最基础的斐波那契数列递归算法。但是大家都知道,函数运行的时候,会被放入函数执行栈运行,如果内部还有函数,那么就会继续入栈,直到最内部函数,然后再一个个出栈,直到栈清空,取得结果。把上边的函数放入控制台运行,就会发现,当n比较大的时候,大概50以上函数栈就会非常大,以至于计算机几分钟内不能算出结果。那么可想而知,当n越来越大的时候,用这个函数,几乎不能算出结果了。所以我们可以用尾递归去优化它。

2:尾递归计算:

function fibonacci(n,a1 = 1,a2 = 1){
    if(n == 1||n == 2) return a2
    return fibonacci(n - 1,a2,a1 + a2)
}
fibonacci(5)
>> 5
fibonacci(50)
>> 12586269025

从这个函数可以看出,我们的递归每次返回的时候,我们把计算结果传入下一个函数,return放在最后,只返回一个函数调用,那么上一个函数其实是已经结束了函数的调用的,此时他会从栈中弹出,那么函数执行栈始终只有一个。把这段函数复制到控制台运行,可以看出,即便是n很大,也能很快算出结果。
细心的同学可能发现了,这其实就是一个迭代啊,只不过把迭代计算放入了递归函数的参数中。

3:迭代计算:

function fibonacci(n){
    if(n == 1||n == 2) return 1
    let a1 = 1,a2 = 1
    for(i = 2;i < n;i++){
        [a1,a2] = [a2,a1+a2]
    }
    return a2
}
fibonacci(5)
>> 5
fibonacci(50)
>> 12586269025

普通的迭代计算,也可以很快计算出结果。

4:缓存计算结果:

function fibonacci(n){
    if(n == 1||n == 2) return 1
    if(!fibonacci[n+'']){
        fibonacci[n+''] = fibonacci(n - 1) + fibonacci(n - 2)
    }
    return fibonacci[n+'']
}
fibonacci(5)
>> 5
fibonacci(50)
>> 12586269025
fibonacci(100)
>> 354224848179262000000

这里咱们用缓存计算结果修改第一个普通递归,刚才分析了,普通递归因为函数执行栈太大以至于难以计算出n很大的结果,那么咱们用函数的属性,存放那些已经计算过的结果,如果有,就直接返回,没有的话,给对应的属性 n 赋值再返回,也可以很快计算出结果。但是给函数添加了很多属性,毕竟是占了不少空间,这属于用空间换时间的算法。具体用不用,就取决于使用者的空间成本和时间成本了。

当然,还有一些其他的算法,这里就不一一列举了。有更好算法的同学欢迎评论区留言。

上一篇:小数点保留两位的js正则表达式
下一篇:vue3 setup如何使用emit?

  • 13
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值