有个人想知道,一年之内一对兔子能繁殖多少对?于是就筑了一道围墙把一对兔子关在里面。 已知一对兔子每个月可以生一对小兔子,而一对兔子从出生后第3个月起每月生一对小兔子。假如一年内没有发生死亡现象,那么,一对兔子一年内(12个月)能繁殖成多少对?
| 月份 | 兔子情况 | 兔子对数 |
|---|---|---|
| 1 | 1小 | 1 |
| 2 | 1中 | 1 |
| 3 | 1大 1小 | 2 |
| 4 | 1大 1中 1小 | 3 |
| 5 | 2大 1中 2小 | 5 |
| 6 | 3大 2中 3小 | 8 |
| 月份 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 兔子情况 | 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 | 89 | 144 |
以上规律: 第一个月 第二个月的兔子对数都是一对 从第三个月开始后面每个月的兔子对数都是前两个月的兔子对数之和
问12个月过后兔子对数 144对 20个月 40个月 100个月
//参数n表示月份
//根据月份计算出对应月份的对数
var count =0;//统计fib函数调用的次数
function fib(n){
count ++;
//第二步:结束递归的条件
if(n==2|| n==1){
return 1;//结束条件
}
//第一步:根据规律得到公式
return fib (n-1)+fib(n-2);
}
console.log(fib(10));
console.log("fib函数调用的次数",count)
//fib(20)==>fib(19)+fib(18);20个月的兔子对数就是18个月的兔子对数+19个月的兔子对数
//fib(19)==> fib(18)+fib(17);
//fib(18)==> fib(17)+fib(6);
//...
//fib(4)==> fib(3)+fib(2);
//fib(3)==> fib(2)+fib(1);
//fib(2)==> 1;
//fib(1)==> 1;
//公式: fib(n)==>fib(n-1) + fib(n-2);
递归函数计算斐波拉契数列的问题
递归函数内部自己调用自己的次数太多了(里面有很多重复的计算) 缓存cache:存储数据的容器
| 月份 | 次数 |
|---|---|
| 10 | 109 |
| 11 | 177 |
| 12 | 287 |
| 20 | 13529 |
| 21 | 21891 |
| 22 | 35421 |
解决斐波拉契数列问题
使用缓存来解决斐波那契的问题 缓存 cache : 存储数据的容器 在js中,可以 对象/数组 来表示缓存容器
使用缓存的套路:
-
使用数组或对象来弄出一个缓存容器
-
在计算结果之前,先去缓存容器中查看是否有需要的数据
-
如果有,直接从缓存容器中取出来使用
-
如果没有,先去计算出来结果,在把计算的结果存储到缓存容器中,目的是为了方便复用
参数n表示月份 根据月份计算出对应月份的对数
// 缓存容器
var cache = {
// 键是月份, 值表示对应月份的兔子对数
/*1: 1,
2: 1,
3: 2,
4: 3,
5: 5*/
};
// cache[n] ==> cache[5] ==> 5
// cache[n] ==> cache[6] ==> undefined
var count = 0; // 统计fib函数调用的次数
function fib(n) {
count++;
// 第二步:结束递归的条件
if (n === 2 || n === 1) {
return 1; //结束条件
}
// 第一步:得到公式
// return fib(n - 1) + fib(n - 2);
// 不应该直接来算
// 应该先去缓存中看看有没有对应的值
if(cache[n]){
// if成立,说明缓存中有对应的数据
return cache[n];
}else{
// 说明缓存中没有对应的数据
// 1. 先计算结果
var res = fib(n - 1) + fib(n - 2);
// 2. 把结果存储到缓存中(千万不要忘。缓存白用了)
cache[n] = res;
// 3. 把结果返回出去
return res;
}
}
console.log(fib(100)); // 55
console.log("fib函数调用的次数", count);