问题

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

思路

  当n=1时,只有一种跳法,及f(1)=1,当n=2时,有两种跳法,及f(2)=2,当n=3时,可以从n=1直接跳到n=3,也可以从n=2直接跳到n=3,及f(3)=f(1)+f(2)=3...,所以可以使用递归,自顶向下,一步一步求解,但是仔细分析一下,如果n=10,需要求得f(9)和f(8),而f(9)=f(8)+f(7),f(8)=f(7)+f(6),可以很明显看到,求了重复的f(8)和f(7),随着n增大,这种复杂度是呈指数倍增长。

package offer009;

import java.util.Scanner;
import java.util.concurrent.TimeUnit; /**
* @Title: Main.java
* @Package: offer009
* @Description 青蛙跳台阶,递归实现(计算量大)
* @author Han
* @date 2016-4-18 下午1:24:17
* @version V1.0
*/ public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in);
int n = 0; while(scanner.hasNext()){ n = scanner.nextInt();
//开始时的纳秒
long start = System.nanoTime();
long steps = getSteps(n);
//花费的纳秒数
long during = System.nanoTime() - start;
//将纳秒转换为毫秒
long seconds = TimeUnit.MILLISECONDS.convert(during, TimeUnit.NANOSECONDS); System.out.println(steps);
System.out.println("当n为" + n + "时,花费时间为" + seconds + "毫秒");
}
} private static long getSteps(int n) { if(n < 1)
throw new RuntimeException("Error Input"); if(n == 1)
return 1;
else if(n == 2)
return 2;
else
return getSteps(n - 1) + getSteps(n - 2);
}
}

测试

  当n>40的时候,就会发现计算已经开始变慢了。

思路

  另一种解法,子底向上方法,类似于动态规划,此次的结果为下回计算的使用,大量减少计算时间。

package offer009other;

import java.util.Scanner;
import java.util.concurrent.TimeUnit; /**
* @Title: Main.java
* @Package: offer009other
* @Description 青蛙跳台阶,动态规划实现(计算量大)
* @author Han
* @date 2016-4-18 下午1:38:17
* @version V1.0
*/ public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in);
int n = 0; while(scanner.hasNext()){ n = scanner.nextInt();
//开始时的纳秒
long start = System.nanoTime();
long steps = getSteps(n);
//花费的纳秒数
long during = System.nanoTime() - start;
//将纳秒转换为毫秒
long seconds = TimeUnit.MILLISECONDS.convert(during, TimeUnit.NANOSECONDS); System.out.println(steps);
System.out.println("当n为" + n + "时,花费时间为" + seconds + "毫秒");
}
} private static long getSteps(int n) { long forgStepMinusOne = 2;
long forgStepMinusTwo = 1;
long steps = 0; for(int i = 3; i <= n; i++){ //当前n步有的跳法
steps = forgStepMinusOne + forgStepMinusTwo;
//为下一次的计算做准备,此次求得是n+1-2步的跳法个数
forgStepMinusTwo = forgStepMinusOne;
//为下一次的计算做准备,此次求得是n+1-1步的跳法个数
forgStepMinusOne = steps;
} return steps;
}
}

测试

总结

  递归实现Fibonacci数列易懂,但是进行了太多的无谓的计算。

青蛙跳台阶(Fibonacci数列)的更多相关文章

  1. 【Java】 剑指offer(9) 斐波那契数列及青蛙跳台阶问题

     本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项 ...

  2. [剑指offer]10.斐波那契数列+青蛙跳台阶问题

    10- I. 斐波那契数列 方法一 Top-down 用递归实现 def fibonacci(n): if n <= 0: return 0 if n == 1: return 1 return ...

  3. 青蛙跳台阶问题——剑指offer

    题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶,求该青蛙跳上一个n级台阶总共有多少中跳法. http://www.nowcoder.com/books/coding-interviews?pa ...

  4. Python算法题(一)——青蛙跳台阶

    题目一(青蛙跳台阶): 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 分析: 假设只有一级台阶,则总共只有一种跳法: 假设有两级台阶,则总共有两种跳法: ...

  5. 【校招面试 之 剑指offer】第10-2题 青蛙跳台阶问题

    题目1:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶.求该青蛙跳上一个n级台阶共有多少种跳法? 题目2:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶...也可以一次跳n级台阶.求该青蛙跳上一个 ...

  6. 面试书上一些题目的整理:O(n)复杂度排序年龄 & 青蛙跳台阶

    可以按照年龄的个数,设置99个桶,然后桶内处理. 青蛙跳台阶,每次1阶或者2阶,就是fib数 如果每次1到n阶,那么归纳法可得,是2^(n-1) 另外1*2 覆盖 2*n个矩阵的问题,仍然是Fib数. ...

  7. 剑指 Offer 10- II. 青蛙跳台阶问题

    剑指 Offer 10- II. 青蛙跳台阶问题 Offer 10- II 题目描述: 动态规划方程: 循环求余: 复杂度分析: package com.walegarrett.offer; impo ...

  8. 剑指offer-第二章算法之斐波拉契数列(青蛙跳台阶)

    递归与循环 递归:在一个函数的内部调用这个函数. 本质:把一个问题分解为两个,或者多个小问题(多个小问题相互重叠的部分,会存在重复的计算) 优点:简洁,易于实现. 缺点:时间和空间消耗严重,如果递归调 ...

  9. 剑指offer 9-10:青蛙跳台阶与Fibonacii数列

    题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果). 问题分析 我们将跳法个数y与台阶数n视为一个函数关系,即y=f(n). ...

随机推荐

  1. Object Pascal 过程与函数

    过程与函数 过程与函数是实现一定功能的语句块,是程序中的特定功能单元.可以在程序的其他地方被调用,也可以进行递归调用.过程与函数的区别在于过程没有返回值,而函数有返回值. 1.过程与函数的定义 过程与 ...

  2. poj 1144 Network(无向图求割顶数)

    题目链接:poj 1144 题意就是说有 n(标号为 1 ~ n)个网点连接成的一个网络,critical places 表示删去后使得图不连通的顶点,也就是割顶,求图中割顶的个数. 直接上大白书上的 ...

  3. java实现数据库连接池

    package com.kyo.connection; import java.sql.Connection; import java.sql.DatabaseMetaData; import jav ...

  4. Druid 数据库用户密码加密 代码实现

    druid-1.0.16.jar 阿里巴巴的开源数据连接池 jar包 明文密码+私钥(privateKey)加密=加密密码 加密密码+公钥(publicKey)解密=明文密码 程序代码如下: pack ...

  5. 深入理解JVM-3垃圾收集器与内存分配策略

    在上面一篇文章中,介绍了java内存运行时区域,其中程序计数器.虚拟机栈.本地方法栈3个区域随线程生灭:栈中的栈帧随着方法的进入和退出而有条不紊的执行着进栈出栈的操作,每一个栈帧中分配着多少内存基本上 ...

  6. java里的基本数据类型

    java里一共有八大数据类型 boolean(未定) char(2字节) byte(1字节) short(2字节) int(4字节) long(8字节) float(4字节) double(8字节), ...

  7. 能在CAD2004以下版本里面打开2007以上版本文件的外挂

    下载地址:http://yunpan.cn/cjrxMKNubXQ5E  访问密码 1974 老何CAD工具安装办法:[推荐]先安装老何工具箱,然后用[扩展添加老何cad下拉菜单.bat]就完成老何下 ...

  8. virtualBox虚拟机安装与主机互访和实现上网配置

    1.到官方网下载vitualBox虚拟机,目前最新版本5.0,并安装. https://www.virtualbox.org/ 2.下载安装CentOS系统安装文件 本文采用CentOS-6.5-i3 ...

  9. docker居然需要3.10以上的内核

    本来想用下docker来安装部署多个MySQL实例呢,居然发现其需要3.10以上内核,对于使用centos6的人来说,是不能满足的. https://docs.docker.com/installat ...

  10. sqlserver计算表使用大小sql

    ) create table #spt_space ( ) null, [rows] int null, ) null, ) null, ) null, ) null ) set nocount on ...