一个小青蛙,可以一次跳两节楼梯,也可以一次跳一节楼梯,请问他如果要跳101节楼梯,一共有几种跳法方案? - 菲波那切数列

数字银月渡
• 阅读 2570

一个小青蛙,可以一次跳两节楼梯,也可以一次跳一节楼梯,请问他如果要跳101节楼梯,一共有几种跳法方案?

问题的描述很简单,看到这个题目的时候,我首先想到的就是举例分析一波,比如当n=1的时候有几种方案,当n=2的时候有几种方案等等….

我们首先分析一波,当n=1的时候,这个时候小青蛙只有一种跳法,就是跳上台阶1,然后结束,当然这并不能帮助我们归纳总结,然后我们继续分析
当n=2的时候,这个时候,小青蛙可以跳上台阶1,也可以跳上台阶2结束,然后台阶1呢,也可以跳上台阶2然后结束,我们发现,如果光靠想象的话,很难发现其中的规律,这个时候我们需要借助图形来帮助我们.

下图是我自己用笔画的图形,建议在这种时候还是用笔在纸上写写画画来帮助我们

一个小青蛙,可以一次跳两节楼梯,也可以一次跳一节楼梯,请问他如果要跳101节楼梯,一共有几种跳法方案? - 菲波那切数列
灵魂画手!!!

经过举例我们发现,得到的结果组成的数,特别像菲波纳斯数列,从n=3开始,每一项都等于前两项的和,为了验证一下我们的结论,我们可以在推导一下n=5的时候,一共有几种情况,很显然我们的结论是正确的.这就是一个求菲波纳斯数列的题,那么好,这个时候有人可能会说了,菲波纳斯数列是啥?能吃么?好,那我就从另外一个角度去分析这个题目

假如说,小青蛙现在已经跳上了第4个台阶,那么它上一个台阶是那一个呢?要想回答这个问题,我们还需要在看一下题目的介绍,题目说,小青蛙一次只能跳一个台阶或者跳两个台阶,那么这个答案很简单了,如果他现在在4,那么它的上一个台阶一定是3或者是2.
然后我们在思考.如果他现在处在第3个台阶呢,那么它的上一个台阶一定是2或者是1.

那你也许会有疑问了,知道了这个他的上一个台阶有啥用呢,我给大家举一个栗子大家就明白了
请问,1+1等于多少呢?如果我在问你,1+1+1的结果呢,很显而易见,我要告诉大家的不是这个等式的结果是多少,我想告诉大家的是算的过程,我们在算出来1+1之后,如果在算1+1+1,我们只需要将1+1的结果在加上1就好,反过来我们理解一下,如果你想算出来1+1+1,那我们是不是只需要算出1+1的结果呢,

类比到我们的这个算法,如果你想算出来小青蛙跳上第4个台阶一共有几种情况,那我们只需要算出来小青蛙跳上第3个的种类加上跳上第2个台阶的种类即可归纳出来的数学公式就是f(n)=f(n-1)+f(n-2).

我们把这个思路由代码实现出来,很简单,我们首先用递归去做.

function jump(n) {
        if (n === 1 || n=== 2) {
            return n
        }
        return jump(n - 1) + jump(n - 2)
    }

代码很简单,但是有一个很大的问题想算出来n=101,根本算不出来,浏览器执行的时间太长,当然,如果你愿意等,浏览器还是可以算出来的.
其实这个代码有一个很大的弊端就是,他会一直重复性的去计算,假设说我们已经算出来f(4)了,但是当我们在算f(5)的时候,这个函数又会从新去算一遍f(4),根据这个思路我们可以优化一下,我们通过一个数组去记录f(n),这样就不会重复性的去计算.

function jump(n, memory = []) {
        if (n === 1 || n=== 2) {
            memory[n] = n
        }
        if (memory[n] !== undefined) {
            return memory[n]
        } else {
            memory[n] = jump(n - 1, memory) + jump(n - 2, memory)
        }
        return memory[n]
    }

改善后的代码,可以’ 秒’算出来结果了,但是我们的追求不能止步于此,我们在优化一下代码,这个代码是通过递归去做的,其实递归是很消耗性能的,我们直接通过循环去做
function jump(n) {

    let arr = [1, 2]
    for (let i = 2; i< n; i++) {
        arr [i] = arr[i - 1] + arr[i - 2]
    }
    return arr[n - 1]
}

最终我们对比通过循环代码和优化后的递归算法执行的时间,我们计算当n = 1000的时候的结果

一个小青蛙,可以一次跳两节楼梯,也可以一次跳一节楼梯,请问他如果要跳101节楼梯,一共有几种跳法方案? - 菲波那切数列

结果显而易见.

最后分享给大家一句话: 大佬不是一天练成的!!!加油,咸鱼总有翻身的一天,就算翻身还是咸鱼,那它也是一条会翻身的咸鱼!!!

点赞
收藏
评论区
推荐文章
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
待兔 待兔
1年前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Easter79 Easter79
3年前
typescript 简版跳一跳
typescript简版跳一跳学习typescript,第一步应该是学习官方文档,理解最基础的语法。第二步开始用typescript实现一些jscss或者canvas类型的游行。现在开始我们用ts写跳一跳核心点:1.场景的随机创建    2.旗子的跳动    3.落脚点的判断,重点要提及的是射线判断法
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
徐小夕 徐小夕
4年前
antd popover定位不准闪跳解决+自己实现popover库
前言我在写H5dooring(https://github.com/MrXujiang/h5Dooring)时,发现我们用的popover会发生闪跳,而且第一次闪跳就算了,每次还会有另一个方向的闪跳。于是我大概百度了下,基本都说需要给固定宽高即可,让后试了下发现没用,就算触发组件和弹窗元素都给了宽高,也一样闪跳。由于antd的popover底层
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
可莉 可莉
3年前
14、OpenCV实现图像的空间滤波——图像锐化及边缘检测
1、图像锐化理论基础1、锐化的概念   图像锐化的目的是使模糊的图像变得清晰起来,主要用于增强图像的灰度跳变部分,这一点与图像平滑对灰度跳变的抑制正好相反。而且从算子可以看出来,平滑是基于对图像领域的加权求和或者说积分运算的,而锐化则是通过其逆运算导数(梯度)或者说有限差分来实现的。2、图像的一阶微分和二阶
Stella981 Stella981
3年前
Android微信跳一跳,自动跳App实现
微信小游戏跳一跳刚推出,不错,简单好玩!但是程序员最烦的就是一直重复做一件事情,所以,能不能自动跳一跳?元旦放假,研究了一下,具体思路分享给大家。先上图!(https://static.oschina.net/uploads/space/2018/0102/090017_DL1U_223115.jpg)图像识别和处理使用的是o
十月飞翔 十月飞翔
3年前
路由协议分为哪几类
首先路由协议分两类:1.静态路由协议手动写目的和下一跳,大量路由数目的时候不适合使用,因为命令写起来比较复杂,多线路的时候选路死板不够灵活.2.第二种是动态路由协议,可以根据自己的算法决定选择合适的路径动态路由协议分两类:内部网关协议.igp:1.内部协议分两类,一类是距离矢量协议目前
陈杨 陈杨
1个月前
鸿蒙5开发宝藏案例分享---一多分级导航栏开发实践
✨鸿蒙开发宝藏踩坑经验:手把手教你玩转多端分级导航栏✨Hey小伙伴们!今天在撸代码时意外挖到了鸿蒙官方文档里藏着的"多端分级导航栏"黄金案例!这个方案完美解决了我在手机/平板/PC端反复横跳的适配焦虑,必须立刻马上分享给你们!🚀一、先唠唠这个方案有多香有
贾蔷 贾蔷
1个月前
洛谷P1255题 解题思路和步骤 C++实现带注释,c++入门基础题
一、问题描述与递推关系建立洛谷P1255数楼梯问题要求计算n级台阶的不同走法数,每次可以跨1级或2级。这本质上是斐波那契数列的变种问题,递推公式为f(n)f(n1)f(n2)。当n≤50时可用普通整型存储,但题目中n可能达到5000,这就必须使用高精度运