一、简单的费波纳切数列
1 public class FbDemo01 { 2 3 public static void main(String[] args) { 4 for(int i=1;i<5;i++){ 5 int j = Fbi(i); 6 System.out.println(j); 7 } 8 } 9 10 private static int Fbi(int i) { 11 if(i<2){ 12 return i == 0 ? 0 : 1; 13 } 14 int a = Fbi(i-1) + Fbi(i-2); 15 return a ; 16 } 17 }
二、Scanner类结合费波纳切数列
在Scanner类中提供了一个可以接收InputStream类型的构造方法,这就表示只要是字节输入流的子类都可以通过Scanner类进行方便的读取。
Scanner类是用于扫描输入文本的。
可以使用该类创建一个对象:Scanner reader=new Scanner(System.in);
然后reader调用下面的方法,读取用户在命令行输入的各种类型的数据
int nextInt(); //将输入信息的下一个标记扫描为一个 int
double nextDouble(); //将输入信息的下一个标记扫描为一个double
...
String nextNext(); //查找并返回来自此扫描器的下一个完整标记(字符串)
String nextLine(); //此扫描器执行当前行,并返回跳过的输入信息
...
boolean hasNext(); //如果此扫描器的输入中有另一个标记,则返回true
boolean hasNext(Pattern pattern); //如果下一个完整标记与指定模式匹配,则
返回true
boolean hasNext(String pattern); //如果下一个标记与从指定字符串构造的模式
匹配,则返回true
boolean hasNextInt(); //如果通过使用nextInt()方法,此扫描器输入信息中的下
一个标记可以解释为指定基数中的一个int 值,则返回true。
1 import java.util.*; 2 import java.io.*; 3 public class fibonacci { 4 public static int k=0; 5 public static void main(String[] args) { 6 Scanner cin=new Scanner(System.in); //Scanner类这是一个用于扫描输入文本的 7 long a=cin.nextLong(); //将输入信息的下一个标记扫描为一个long 8 System.out.println(fibonacci(a)); 9 System.out.println("共调用了"+k+"次"); 10 } 11 public static long fibonacci(long m){ 12 if(m==0|m==1){ 13 k++; 14 return m; 15 }else{ 16 return fibonacci(m-1)+fibonacci(m-2); 17 } 18 } 19 }
三、 递归的缺点:
会造成调用栈的溢出,因为需要为每一次函数调用在内存栈中分配空间,而每个进程的栈的容量是有限的。当递归调用层级太多时,就会超出栈的容量,从而导致调用栈溢出。
同时,斐波纳契数类的特点:前面相邻两项的和,构成了后一项。
利用次特点,可以改进上面的程序,避免栈的溢出:
1 package test02; 2 3 import java.util.Scanner; 4 5 public class Fibonacci { 6 public static void main(String[] args) { 7 Scanner cin=new Scanner(System.in); //Scanner类这是一个用于扫描输入文本的 8 int a=cin.nextInt(); //将输入信息的下一个标记扫描为一个long 9 System.out.println(Fibonacci(a)); 10 11 } 12 13 public static int Fibonacci(int n) { 14 if(n==0){ 15 return 0; 16 } 17 if(n==1){ 18 return 1; 19 } 20 int numfn1=0; 21 int numfn2=1; 22 int currentfn=0; 23 for(int i=2;i<=n;i++){ 24 currentfn=numfn1+numfn2; 25 numfn1=numfn2; 26 numfn2=currentfn; 27 } 28 return currentfn; 29 } 30 }
四、青蛙跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
思路:当前台阶的跳法总数=当前台阶后退一阶的台阶的跳法总数+当前台阶后退二阶的台阶的跳法总数。
1 package test02; 2 3 import java.util.Scanner; 4 5 public class JumpFloorDemo { 6 7 public static void main(String[] args) { 8 Scanner cin=new Scanner(System.in); //Scanner类这是一个用于扫描输入文本的 9 int a=cin.nextInt(); //将输入信息的下一个标记扫描为一个long 10 System.out.println(Fibonacci(a)); 11 } 12 13 private static int Fibonacci(int a) { 14 if(a==2||a==1){ 15 return a; 16 } 17 // 第一阶和第二阶考虑过了,初始当前台阶为第三阶,向后迭代 18 19 // 思路:当前台阶的跳法总数=当前台阶后退一阶的台阶的跳法总数+当前台阶后退二阶的台阶的跳法总数 20 int currentjumpSum=0;//当前台阶的跳法总数 21 int jumpSumBackStep1=2;//当前台阶后退一阶的台阶的跳法总数 22 int jumpSumBackStep2=1;//当前台阶后退二阶的台阶的跳法总数 23 for(int i=3;i<=a;i++){ 24 currentjumpSum=jumpSumBackStep1+jumpSumBackStep2; 25 jumpSumBackStep2=jumpSumBackStep1;// 后退一阶在下一次迭代变为后退两阶 26 jumpSumBackStep1=currentjumpSum;// 当前台阶在下一次迭代变为后退一阶 27 } 28 return currentjumpSum; 29 } 30 31 }
五、矩阵覆盖
用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
有以下几种情形:
(1) target <= 0 大矩形为<= 2*0,直接return 1;
(2) target = 1大矩形为2*1,只有一种摆放方法,return1;
(3) target = 2 大矩形为2*2,有两种摆放方法,return2;
(4) target = n 分为两步考虑:
第一次摆放一块 2*1 的小矩阵,则摆放方法总共为f(target - 1)
第一次摆放一块1*2的小矩阵,则摆放方法总共为f(target-2)
因为,摆放了一块1*2的小矩阵(用√√表示),对应下方的1*2(用××表示)摆放方法就确定了,所以为f(targte-2)
1 package test02; 2 3 import java.util.Scanner; 4 5 public class RectCover { 6 public static void main(String[] args) { 7 Scanner cin=new Scanner(System.in); //Scanner类这是一个用于扫描输入文本的 8 int a=cin.nextInt(); //将输入信息的下一个标记扫描为一个long 9 System.out.println(Fibonacci(a)); 10 } 11 12 private static int Fibonacci(int a) { 13 if (a < 1) { 14 return 0; 15 } else if (a == 1 || a == 2) { 16 return a; 17 } else { 18 return Fibonacci(a-1) + Fibonacci(a-2); 19 } 20 } 21 }