/**
* 剑指offer面试题9:斐波那契数列
*
* 题目:写入一个函数,输入n,求斐波那契数列的第n项。
*
* 考察:递归,循环,时间复杂度的理解
*
* 推荐方式:用循环来解
*
* 应用1:一只青蛙一次可以跳上1级台阶,也可以跳上2级,求该青蛙跳上一个n级台阶总共有多少中跳法。
*
* 相关题目:我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用8个2*1的小矩形无重叠覆盖
* 一个2*8的大矩形,总共有多少种方法? -----(仍然是斐波那契数列)
*
* 扩展,如果青蛙跳台阶,条件改成,一只青蛙一次可以跳上1级台阶,也可以跳上2级....它也可以跳上n级,
* 此时该青蛙跳上一个n级的台阶总共有多少种方法?
* 1.如果起始跳一阶的话,剩余的n-1阶就有 f(n-1) 种跳法;
* 2.如果起始跳二阶的话,剩余的n-2阶就有 f(n-2) 种跳法;
* 3.如果起始跳三阶的话,剩余的n-2阶就有 f(n-3) 种跳法;
* ...
* n.如果起始跳n阶的话,剩余的n-2阶就有 f(n-n) 种跳法;
* f(n) = f(n-1)+f(n-2)+......+f(n-(n-1))+f(n-n)
* f(n-1) = f(n-2)+f(n-3)+.......+f(0)
* -> f(n) = 2* f(n-1)
* = 2^2 * f(n-2)
* = 2^(n-2) * f(2)
* 又f(0)=1,当台阶只有一级的时候,f(1) = 1
* 故: f(2) = f(0) + f(1) = 2
* 因此: f(n) = 2^(n-1)种方法
*/
public class Fibonacci {
//用递归的解法虽然直观,但是时间效率很低,因为很多项重复计算,导致很容易超时
public static int fib_1(int n) {
if(n <= 0) {
return 0;
}else if (n == 1) {
return 1;
}
return fib_1(n-1) + fib_1(n-2);
}
//循环实现,提高了时间效率,时间复杂度为O(n)
public static int fib_2(int n) {
int[] result = {0,1};
if(n < 2) {
return result[n];
}
int f1 = 1;
int f2 = 0;
int fibN = 0;
for (int i = 2; i <=n; i++) {
fibN = f1 + f2;
f2 = f1 ;
f1 = fibN;
}
return fibN;
}
public static void main(String[] args) {
System.out.println(fib_1(1));
System.out.println(fib_1(2));
System.out.println(fib_1(5));
System.out.println(fib_1(44));
System.out.println();
System.out.println(fib_2(1));
System.out.println(fib_2(2));
System.out.println(fib_2(5));
System.out.println(fib_2(44));
}
}