JS 从斐波那契数列浅谈递归
一、前言
昨晚下班后,经理出于兴趣给我们技术组讲了讲算法相关的东西,全程一脸懵逼的听,中途还给我们出了一道比较有趣的爬楼问题,问题如下:
假设一个人从地面开始爬楼梯,规定一步只能爬一坎或者两坎,人只能往上走,例如爬到第一坎,很明显从地面到第一坎只有一种可选方式,从地面爬到第二坎,他可以从地面直接跨到第二坎,也可以先从地面到第一坎,再从第一坎到第二坎,也就是2种可选方式,那么求他爬到N楼一共有几种可选方式。
这道题涉及到了斐波那契数列,要求使用递归来求值,技术贼菜的我也是一脸懵逼,所以本着学习的心还是记录下来了。
二、有趣的斐波那契数列
我们将地面理解为数字0,第一坎理解为数字1,以此来进行简单的分析:
例如从0到1,就一种选择,如图(公司不让用破解软件,没PS画图,凑合看吧,画图的手微微颤抖。。。)
那么,现在要求到第二坎,从0到2呢,两种选择,看图分析(记住,一步只能跨一坎或者两坎):
当要求从0到3,三种选择,如图:
紫色:一坎坎的走;黄色:先走两坎,再走一坎;蓝色:先走一坎,再走两坎。
从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是根据实际情况来定的,这点不用纠结。
三、斐波那契数列与递归的结合
什么是递归?自己调用自己的函数就是递归,这么说完全没问题。
我们回归上面的问题,要求第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 = ;
if (n === ){
step +=
}else if (n === ){
step += ;
}else if (n >= ){
step = recursion(n-) + recursion(n-);
};
return step;
};
console.log(recursion())//89种
为了验证,我将上方分支图中所有的1与2相加(1层只有1种走法,2层有2种),得出数字也确实是89。所以我不明白我为什么要把基数N设置为10,算的难受。
那么趁热打铁,活学活用,现在我们尝试求正整数N与N之前所有正整数累加的和。
例如3之前累加的和就是3+2+1,数字0加不加没意义,所以跳出递归的临界条件就是当N>=2时,最后调用一次让之前数字的和加一次1就好了。
var result = ;
function add(n){
result += n
n>= ? add(n-) : null;
return result;
};
console.log(add());//
验证一下,完全没问题,有没有觉得递归挺简单。
当你看到这时,恭喜你,不仅了解了斐波那契数列,也简单了解了递归的用法。其实本人在工作中需要操作数据,本能的总是想到穷举,循环,那么现在又多了一种可行的解决方法,也算是对于思维的开拓了。
留个问题,回到上方两段实现代码,为什么第一个变量申明在函数体内,而第二个数字累加的变量申明要在函数体外呢?尝试思考下。
当然,前提是,这篇博客如果有人愿意看完就挺好了。
JS 从斐波那契数列浅谈递归的更多相关文章
- JS实现斐波那契数列的几种方法
斐波那契数列指的是这样一个数列:1.1.2.3.5.8.13.21.34.…… 前两项为1,从第三项起,每一项等于前两项的和,即F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n& ...
- JS写斐波那契数列的几种方法
斐波那契数,指的是这样一个数列:1.1.2.3.5.8.13.21.……在数学上,斐波那契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=Fn-1+Fn-2(n>=2,n∈N*),用文字 ...
- JS实现斐波那契数列的五种方式
下面是五种实现斐波那契数列的方法 循环 function fibonacci(n){ var res1 = 1; var res2 = 1; var sum = res2; for(var i = ...
- 斐波那契数列PHP非递归数组实现
概念: 斐波那契数列即表达式为 a(n) = a(n-1)+a(n-2) 其中 a1 =0 a2 = 1 的数列 代码实现功能: 该类实现初始化给出n,通过调用getValue函数得出a(n)的值 ...
- js实现斐波那契数列
1:递归 function fb1(n){ if(n <= 2){ return 1; }else{ return fb1(n-1) + f ...
- JS求斐波那契数列的N项
第一种求法: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF- ...
- callee和斐波那契数列
如果一对兔子每月生一对兔子:一对新生兔,从第二个月起就开始生兔子:假定每对兔子都是一雌一雄,试问一对兔子,第n个月能繁殖成多少对兔子? ———————————————————————————————— ...
- 剑指offer-第二章算法之斐波拉契数列(青蛙跳台阶)
递归与循环 递归:在一个函数的内部调用这个函数. 本质:把一个问题分解为两个,或者多个小问题(多个小问题相互重叠的部分,会存在重复的计算) 优点:简洁,易于实现. 缺点:时间和空间消耗严重,如果递归调 ...
- 剑指offer【07】- 斐波那契数列(java)
题目:斐波那契数列 考点:递归和循环 题目描述:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0),n<=39. 法一:递归法,不过递归比较慢, ...
随机推荐
- boost asio 学习(八) 网络基础 二进制写发送和接收
http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting- started-with-boostasio?pg=9 8. Net ...
- mysql c-api 预处理语句
stmt = mysql_stmt_init(mysql) mysql_stmt_prepare(stmt, "SELECT ?", strlen("SELECT ?&q ...
- Rsync常见错误和问题
五.常见问题 以下是为配置rsync时的常见问题: 问题一:@ERROR: chroot failedrsync error: error starting client-server protoco ...
- 走进JDK(五)------AbstractList
接下来的一段时间重点介绍java.util这个包中的内容,这个包厉害了,包含了collection与map,提供了集合.队列.映射等实现.一张图了解java中的集合类: AbstractList 一. ...
- app已损坏,打不开。你应该将它移到废纸篓
首先声明: 有可能并非你安装的软件已损坏,而是Mac系统的安全设置问题,因为这些应用都是破解或者汉化的,那么解决方法就是临时改变Mac系统安全设置. 出现这个问题的解决方法: 修改系统配置:系统偏好设 ...
- 【转】Map 与 Unordered_map
map和unordered_map的差别和使用 map和unordered_map的差别还不知道或者搞不清unordered_map和map是什么的,请见:http://blog.csdn.net/b ...
- git 包教包会
# Git全面解析 版本控制工具:VSS.CVS.SVN.Git等,其中Git属于绝对霸主地位. 注意:一般版本控制工具包含两部分 客户端(本地):本地编写内容以及版本记录 服务端(网盘):将内容和版 ...
- 【转】vim 命令
Vim命令合集 建议直接看原文:(排版有些乱) 命令历史 以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令. 启动vim 在命令行窗口中输入以下命令即可 vim 直接 ...
- 9.10 翻译系列:EF数据注解特性之StringLength【EF 6 Code-First系列】
原文链接:https://www.entityframeworktutorial.net/code-first/stringlength-dataannotations-attribute-in-co ...
- Vue自定义指令,ref ,sync,slot
一.自定义指令 vue中可以自己设置指令,通过directive来实现,有2种创建方式,一种是局部创建,一种是全局创建. 第一种:局部创建 如果想注册局部指令,组件中也接受一个 directives ...