JS 从斐波那契数列浅谈递归

1、前言算法

昨晚下班后,经理出于兴趣给咱们技术组讲了讲算法相关的东西,全程一脸懵逼的听,中途还给咱们出了一道比较有趣的爬楼问题,问题以下:闭包

假设一我的从地面开始爬楼梯,规定一步只能爬一坎或者两坎,人只能往上走,例如爬到第一坎,很明显从地面到第一坎只有一种可选方式,从地面爬到第二坎,他能够从地面直接跨到第二坎,也能够先从地面到第一坎,再从第一坎到第二坎,也就是2种可选方式,那么求他爬到N楼一共有几种可选方式。函数

这道题涉及到了斐波那契数列,要求使用递归来求值,技术贼菜的我也是一脸懵逼,因此本着学习的心仍是记录下来了。学习

2、有趣的斐波那契数列spa

咱们将地面理解为数字0,第一坎理解为数字1,以此来进行简单的分析:3d

例如从0到1,就一种选择,如图(公司不让用破解软件,没PS画图,凑合看吧,画图的手微微颤抖。。。)code

那么,如今要求到第二坎,从0到2呢,两种选择,看图分析(记住,一步只能跨一坎或者两坎):blog

当要求从0到3,三种选择,如图:递归

紫色:一坎坎的走;黄色:先走两坎,再走一坎;蓝色:先走一坎,再走两坎。ci

从0-4,一共五种状况,如图:

这里我分开画了,左边的2种状况加上右边的三种状况

左边:

第一种:一坎坎的走,0-1-2-3-4

第二种:两坎两坎走,0-2-4

右边:

第三种:先走两坎,再一坎坎的走0-2-3-4

第四种:先走一坎,再走两坎,再走一坎0-1-3-4

第五种:先走一坎,再走一坎,再走两坎0-1-2-4

当咱们继续日后画,楼梯层对应走法会造成一个有趣的规律,

从第三层开始,第三层的走法等于一层与二层走法的和,第四层的走法等于第二层和第三层走法的和.....针对楼梯问题,咱们能够获得以下公式:

F(n) = F(n-1) + F(n-2)   n>=3

这就是著名的斐波那契数列(Fibonacci sequence),又称黄金分割数列。有兴趣的同窗能够查查兔子繁殖问题。

百科里斐波那契数列的基数n>=4是根据实际状况来定的,这点不用纠结。

3、斐波那契数列与递归的结合

什么是递归?本身调用本身的函数就是递归,这么说彻底没问题。

咱们回归上面的问题,要求第N层的走法,那咱们只须要知道N-1层和N-2层的走法就行了,假设N是10,求到第十层的走法。

十层走法=九层的走法+八层走法

九层和八层也能够拆分啊,九层走法 = 七层走法 + 八层走法 ,而八层走法 = 七层走法 + 六层走法

.......

当分到3层时,最后还能够拆分为1层+2层,由于规律是从第三层开始的,由于此公式不适用于1层和2层,分到1层和2层就表明分支的结束了。

使用闭包须要找到跳出本身调用本身的的临界条件,否则会会陷入死循环,那对应咱们的楼梯问题,只要N<3时就不须要继续调用本身了,由于不须要继续产生分支了。

这个闭包怎么写呢?咱们结合斐波那契数列公式尝试一下吧。

如今有一个函数,里面申明一个走法变量var step = 0;输入一个数字N,咱们会对N判断,只要N>=3,它就会本身调用本身,小于3时,咱们分别判断它等于1或者2,等于1就让step加1,等于2就让step加2,以下:

function recursion(n){
    let step = 0;
    if (n === 1 ){
        step += 1
    }else if (n === 2){
        step += 2;
    }else if (n >= 3){
        step = recursion(n-1) + recursion(n-2);
    };
    return step;
};
console.log(recursion(10))//89种

为了验证,我将上方分支图中全部的1与2相加(1层只有1种走法,2层有2种),得出数字也确实是89。因此我不明白我为何要把基数N设置为10,算的难受。

那么趁热打铁,活学活用,如今咱们尝试求正整数N与N以前全部正整数累加的和

例如3以前累加的和就是3+2+1,数字0加不加没意义,因此跳出递归的临界条件就是当N>=2时,最后调用一次让以前数字的和加一次1就行了。

var result = 0;
function add(n){
    result += n
    n>=2 ? add(n-1) : null;
    return result;
};
console.log(add(10));//55

验证一下,彻底没问题,有没有以为递归挺简单。

当你看到这时,恭喜你,不只了解了斐波那契数列,也简单了解了递归的用法。其实本人在工做中须要操做数据,本能的老是想到穷举,循环,那么如今又多了一种可行的解决方法,也算是对于思惟的开拓了。

留个问题,回到上方两段实现代码,为何第一个变量申明在函数体内,而第二个数字累加的变量申明要在函数体外呢?尝试思考下。

固然,前提是,这篇博客若是有人愿意看完就挺好了。

相关文章
相关标签/搜索