剑指offer7:斐波那契数列
题目描述:
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。
n<=39
思路:
递归和循环两种发解法
递归就是f(n)=f(n-1)+f(n-2);但递归的效率低。每次函数调用,都要在内存栈中分配空间以存储参数、返回地址以及临时变量,而且会出现栈溢出
循环就是使用两个参数保存已经计算好的中间项,下次需要计算的时候查找一下,如果存在就不用再计算了。
1 public class Fibonacci { 2 //递归 3 // public int fibonacci(int n){ 4 // if(n==0) return 0; 5 // if(n==1||n==2) return 1; 6 // else { 7 // return fibonacci(n-1)+fibonacci(n-2); 8 // } 9 // } 10 //循环 11 public static int fibonacci(int n){ 12 int first = 1; 13 int second = 0; 14 int result = 0; 15 if(n==0) result = 0; 16 if(n==1||n==2) result = 1; 17 18 for(int i = 2;i<=n;i++){ 19 result = first + second; 20 second = first; 21 first = result; 22 } 23 return result; 24 } 25 public static void main(String[] args) { 26 // TODO Auto-generated method stub 27 int n = 3; 28 System.out.println(fibonacci(n)); 29 } 30 31 }
变形:跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
思路:
n个台阶可以看做f(n),则第一次跳有两个选择,跳一阶或跳两阶,对应剩下n-1即为f(n-1)和f(n-2),即斐波那契数列
再变形:变态跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
数学归纳法可证明f(n)=2^(n-1)
或者使用递归,f(n)=2*f(n-1)
跳1级,剩下n-1级,则剩下跳法是f(n-1)
跳2级,剩下n-2级,则剩下跳法是f(n-2)
所以f(n)=f(n-1)+f(n-2)+...+f(1)
因为f(n-1)=f(n-2)+f(n-3)+...+f(1)
所以f(n)=2*f(n-1)
1 import java.util.*; 2 public class Solution { 3 public int JumpFloorII(int target) { 4 if(target<0) return -1; 5 else if(target==1) return 1; 6 // else return 2*JumpFloorII(target-1); 7 else return (int)Math.pow(2,target-1); 8 } 9 }
再变形:矩阵覆盖
我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
如果小于1,则为0 等于1,则为1
大于等于2,则可以有横着放和竖着放两种情况 横着放则为f(n-1),竖着放则为f(n-2)
又变成斐波那契数列
1 public class Solution { 2 public int RectCover(int target) { 3 if(target < 1){ 4 return 0; 5 } 6 if(target==1)return 1; 7 if(target*2 == 2){ 8 return 1; 9 }else if(target*2 == 4){ 10 return 2; 11 }else{ 12 return RectCover((target-1))+RectCover(target-2); 13 } 14 } 15 }