青蛙跳台阶问题,常见面试算法题,斐波那契数列(Fibonacci Sequence)

来源:互联网 发布:淘宝客服不理人怎么办 编辑:程序博客网 时间:2024/05/17 04:52

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

问题分析
设f(n)表示青蛙跳上n级台阶的跳法数。当只有一个台阶时,
即n = 1时, 只有1中跳法;
当n = 2时,有两种跳法;
当n = 3 时,有3种跳法;
当n很大时,青蛙在最后一步跳到第n级台阶时,有两种情况:
一种是青蛙在第n-1个台阶跳一个台阶,那么青蛙完成前面n-1个台阶,就有f(n-1)种跳法,这是一个子问题。
另一种是青蛙在第n-2个台阶跳两个台阶到第n个台阶,那么青蛙完成前面n-2个台阶,就有f(n-2)种情况,这又是另外一个子问题。

两个子问题构成了最终问题的解,所以当n>=3时,青蛙就有f(n)=f(n-1)+f(n-2)种跳法。上面的分析过程,其实我们用到了动态规划的方法,找到了状态转移方程,用数学方程表达如下:

这里写图片描述

仔细一看,这不就是传说中的著名的斐波那契数列,但是与斐波那契数列的还是有一点区别,斐波那契数列从0开始,f(0)=0,f(1)=1,f(2)=1。斐波那契数列(Fibonacci Sequence),又称黄金分割数列,因为当n趋于无穷大时,前一个数与后一个数的比值无限接近于黄金比例(√5?12的无理数,0.618…)。

下面是实现代码,两种方式,亲测可用,大家如果要测试可以直接拷贝代码粘贴到Java项目中运行即可:

public class Test1 {     public static void main(String[] args) {          System.out.println(frogJumpFloor(4));         //System.out.println(frogJumpFloorII(4));          }       //一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级。求该青蛙跳上一个n 级的台阶总共有多少种跳法。        //1,2,3,5,8,13,21…… 从第三位数开始,以后的数是它前两位数的和     static int frogJumpFloor(int number) {//迭代方法            if(number<=0) return number;            if(number==1) return 1;            if(number==2) return 2;            int jumpone=2;            int jumptwo=1;            int jumpn=0;            for(int i=3;i<=number;i++){//转圈赋值                jumpn=jumptwo+jumpone;                jumptwo=jumpone;                jumpone=jumpn;            }            return jumpn;     }     static int frogJumpFloorII(int n)  {//递归方法         if (n <= 0)      return -1;           if (1 == n)      return  1;           else if (2 == n) return  2;           else {               return frogJumpFloorII(n - 1) + frogJumpFloorII(n - 2);           }       }  }

二、一只青蛙一次可以跳上1级台阶,也可以跳上2 级……它也可以跳上n 级,此时该青蛙跳上一个n级的台阶总共有多少种跳法?(拓展问题)

问题分析

当n = 1 时, 只有一种跳法,即1阶跳:f(1) = 1;
当n = 2 时, 有两种跳的方式,一阶跳和二阶跳:f(2) = f(1) + f(0) = 2;

当n = 3 时,有三种跳的方式,第一次跳出一阶后,后面还有f(3-1)种跳法; 第一次跳出二阶后,后面还有f(3-2)种跳法,一次跳到第三台阶,f(3) = f(2) + f(1)+f(0)=4;

当n = n 时,共有n种跳的方式,第一次跳出一阶后,后面还有f(n-1)种跳法; 第一次跳出二阶后,后面还有f(n-2)种跳法….第一次跳出n阶后, 后面还有f(n-n)种跳法。

所以f(n) = f(n-1)+f(n-2)+f(n-3)+………. +f(n-n) = f(0)+f(1)+f(2)+…….+f(n-2)+f(n-1),
又因为f(n-1) = f(n-2)+f(n-3)+…+f(n-n) = f(0)+f(1)+f(2)+…….+f(n-2),
两式相减得:f(n)-f(n-1)=f(n-1),所以f(n) = 2*f(n-1),n >= 2。
这里写图片描述

下面是实现代码,两种方式,亲测可用,大家如果要测试可以直接拷贝代码粘贴到Java项目中运行即可:

public class Test2 {     public static void main(String[] args) {           System.out.println(frogJumpFloor(3));         //System.out.println(frogJumpFloorII(3));          }      //一只青蛙一次可以跳上1级台阶,也可以跳上2 级……它也可以跳上n 级,    //此时该青蛙跳上一个n级的台阶总共有多少种跳法?          static int frogJumpFloor(int number) {//迭代方法            int count=1;            if(number==1) return 1;            else{                for(int k=2;k<=number;k++)                    count=2*count;                return count;            }     }     static int frogJumpFloorII(int number) {//递归方法            if(number==1)return 1;            return 2*frogJumpFloorII(number-1);     }}

拓展问题可能逻辑思维不强的开发者理解起来比较困难,如果你看一遍理解不了就看三遍,三遍不行就三十遍、三百遍……
我是属于比较笨的人,看了好多个三十遍才理解,有时候只想说:在座的各位只有我是垃圾!
如果还是不能理解,好在两种实现的代码比简单,尤其递归的方法就两行代码,大家可以死记硬背来搞定面试。

1 0
原创粉丝点击