关于斐波那契数列那些事

版权声明:本文为博主原创文章,未经博主允许不得转载。如果对你有帮助,那真是再好不过啦~ https://blog.csdn.net/SCU_Cindy/article/details/73729648

最近在做题的时候,发现了一个有趣的东西,叫做斐波那契数列。这个可谓说是笔试必考递归之一。有点好玩。首先来看一下斐波那契数列定义。

斐波那契数列Defination

斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368。特别指出:第0项是0,第1项是第一个1,这个数列从第3项开始,每一项都等于前两项之和。斐波那契数列也称为黄金数列。

在数学上,斐波纳契数列以如下被以递归的方法定义:

f(0)=0,f(1)=1,f(n)=f(n1)+f(n2),nNn2

接下来以几道题来试试斐波那契数列的用法。

第一道题,定义编程题

  • 题目描述
    要求输入一个整数n,请你输出斐波那契数列的第n项。(n<=39)

  • 代码解答

function Fibonacci(n)
{
    if(n==0){
        return 0;
    }else if(n==1){
        return 1;
    }
    var FibonacciArray = [0,1];
    for(var i=2; i<=n; i++){
        FibonacciArray.push(FibonacciArray[i-1] + FibonacciArray[i-2]);
    }

    return FibonacciArray.pop();
}

第二道题,青蛙跳台阶问题

  • 题目描述
    一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

  • 代码解答

function jumpFloor(number)
{
    if(number <= 2){
        return number;
    }
    var arr = [0,1,2];
    for(var i=3;i<=number;i++){
        arr.push(arr[i-1] + arr[i-2]);
    }

    return arr.pop();
}

第三道题,变态跳台阶问题

  • 题目描述
    一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

  • 思路分析
    关于本题,前提是n个台阶会有一次n阶的跳法。分析如下:
    f(1)=1
    f(2)=f(21)+f(22)//f(22)22
    f(3)=f(31)+f(32)+f(33)
    ...
    f(n)=f(n1)+f(n2)+f(n3)+...+f(n(n1))+f(nn)
    说明:
    1) 这里的f(n) 代表的是n个台阶有一次1,2,…n阶的 跳法数。
    2) n = 1时,只有1种跳法,f(1) = 1
    3) n = 2时,会有两个跳得方式,一次1阶或者2阶,这回归到了问题(1),f(2) = f(2-1) + f(2-2)
    4) n = 3时,会有三种跳得方式,1阶、2阶、3阶,那么就是第一次跳出1阶后面剩下:f(3-1);第一次跳出2阶,剩下f(3-2);第一次3阶,那么剩下f(3-3)
    因此结论是f(3) = f(3-1)+f(3-2)+f(3-3)
    5) n = n时,会有n中跳的方式,1阶、2阶…n阶,得出结论:f(n) = f(n-1)+f(n-2)+…+f(n-(n-1)) + f(n-n) => f(0) + f(1) + f(2) + f(3) + … + f(n-1)
    6) 由以上已经是一种结论,但是为了简单,我们可以继续简化:
    f(n-1) = f(0) + f(1)+f(2)+f(3) + … + f((n-1)-1) = f(0) + f(1) + f(2) + f(3) + … + f(n-2);f(n) = f(0) + f(1) + f(2) + f(3) + … + f(n-2) + f(n-1) = f(n-1) + f(n-1)
    可以得出:f(n) = 2*f(n-1)
    7) 得出最终结论,在n阶台阶,一次有1、2、…n阶的跳的方式时,总得跳法为:
    math

  • 代码解答

function jumpFloorII(number)
{
    if(number <= 2){
        return number;
    }else{
        return 2*jumpFloorII(number-1);
    }
}

第四道题,矩形覆盖问题

  • 题目描述
    我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
  • 思路解析
    用归纳法归纳如下:
    1) 当 n < 1时,显然不需要用2*1块覆盖,按照题目提示应该返回 0。
    2) 当 n = 1时,只存在一种情况。
    n=1
    3) 当 n = 2时,存在两种情况。
    n=2
    4) 当 n = 3时,明显感觉到如果没有章法,思维难度比之前提升挺多的。
    n=3
    尝试归纳,本质上 n 覆盖方法种类都是对 n - 1 时的扩展。可以明确,n 时必定有 n-1时原来方式与2*1的方块结合。也就是说, f(n) = f(n-1) + ?(暂时无法判断)。
    5) 如果我们现在归纳 n = 4,应该是什么形式?
    保持原来n = 3时内容,并扩展一个 2*1 方块,形式分别为 “| | | |”、“= | |”、“| = |”;新增加的2*1 方块与临近的2*1方块组成 2*2结构,然后可以变形成 “=”。于是 n = 4在原来n = 3基础上增加了”| | =”、“= =”; 再自己看看这多出来的两种形式,是不是只比n = 2多了“=”。其实这就是关键点所在…因为,只要2*1或1*2有相同的两个时,就会组成2*2形式,于是就又可以变形了。
    6) 所以,自然而然可以得出规律: f(n) = f(n-1) + f(n-2), (n > 2)。
  • 拓展发散
    如果看了这一套理论还存在疑惑。可以尝试将题目改成1*3方块覆盖3*n、1*4方块覆盖4*n。相应的结论应该是:
    (1)1 * 3方块 覆 盖3*n区域:f(n) = f(n-1) + f(n - 3), (n > 3)
    (2) 1 *4 方块 覆 盖4*n区域:f(n) = f(n-1) + f(n - 4),(n > 4)
    更一般的结论
    如果用1*m的方块覆盖m*n区域,递推关系式为f(n) = f(n-1) + f(n-m),(n > m)。

  • 代码解答

function rectCover(number)
{
    if(number <= 2){
        return number;
    }
    var arr=[0,1,2];
    for(var i=3;i<=number;i++){
        arr.push(arr[i-1]+arr[i-2]);
    }
    return arr.pop();
}

关于斐波那契数列的应用就到这里啦。个人觉得挺好玩儿的,分析过程和递归推导过程大同小异,是值得学习的。最后,希望这篇文章能对你有所帮助。记得点赞,么么哒。

猜你喜欢

转载自blog.csdn.net/SCU_Cindy/article/details/73729648