题目:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。n<=39
【斐波那契数列】:
1、1、2、3、5、8、13、21、34、55,一个数等于前面两个数相加
【递归法】:
public class Solution {
//1、1、2、3、5、8、13、21、34、55
//F(0)=0,F(1)=1,F(2)=1,F(n)=F(n-1)+F(n-2)
public int Fibonacci(int n) {
//递归法:
if(n<=0){
return 0;
}else if(n==1||n==2){
return 1;
}else{
return Fibonacci(n-1)+Fibonacci(n-2);
//递归本质上就是一个个的栈帧(一个方法开辟一个栈帧),容易栈溢出!
}
}
}
【迭代法】:
public class Solution {
//1、1、2、3、5、8、13、21、34、55
//F(0)=0,F(1)=1,F(2)=1,F(n)=F(n-1)+F(n-2)
public int Fibonacci(int n) {
//迭代法
int a=1,b=1,c=0;//c=a+b
if(n<=0){
return 0;
}else if(n==1||n==2){
return 1;
}else{
for(int i=3;i<=n;i++){
c=a+b;
a=b;
b=c;
}
return c;
}
}
}
【动态规划】:
F[0]=0;F[1]=1;
for(int i=2;i<=N;i++){
F[i]=F[i-1]+F[i-2];
}
分析:
在这里迭代跟动态规划的原理是一样的。
由于递归很耗费堆栈,因此能用动态规划或者递归的,就别用迭代。
【例一】动态规划
【题目】有一只兔子,从出生后第3个月起每个月都生一只兔子,小兔子长到第三个月后每个月又生一只兔子,假如兔子都不死,问每个月的兔子总数为多少?
//遇到此类问题动手写一写:
//mon 1 2 3 4 5 6
//出生 0 0 1 1 2 3
//总数 1 1 2 3 5 8
//斐波那契数列!
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
int month = sc.nextInt();
System.out.println(getTotalCount(month));
}
}
public static int getTotalCount(int month){
int[] arr = new int[100];
arr[1] = arr[2] = 1;
for(int i=3;i<100;i++){
arr[i] = arr[i-1] + arr[i-2];
}
return arr[month];
}
}
【例二】爬楼梯
【题目】假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
例:
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶:
- 1 阶 + 1 阶 + 1 阶
- 1 阶 + 2 阶
- 2 阶 + 1 阶
找规律即可:
n: 1 2 3 4
res: 1 2 3 5
——斐波那契数列
【递归法】
class Solution {
public int climbStairs(int n) {
if(n==1){
return 1;
}else if(n==2){
return 2;
}else{
return climbStairs(n-1) +climbStairs(n-2);
}
}
}
——递归法易超时
【动态规划法】
class Solution {
public int climbStairs(int n) {
int [] res = new int[100];
res[1] = 1;
res[2] = 2;
for(int i=3;i<=n;i++){
res[i] = res[i-1] + res[i-2];
}
return res[n];
}
}