题目描述
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。
思路
- 斐波那契数列在讲的时候就是为了引入递归,f(n)=f(n-1)+f(n-2),天生的递归啊,但问题是,递归需要消耗大量栈的空间,所有递归都需要等待底层的运算完毕;
- 递归不行,那就循环呗
代码
public static void main(String [] arg)
{
System.out.println(Fibonacci1(3));
}
static public int Fibonacci(int n) {
if ( n<= 0 )
return 0 ;
if (n == 1 )
return 1;
else
return Fibonacci(n-1)+Fibonacci(n-2);
}
static public int Fibonacci1 (int n)
{
if ( n<2)
return n;
int x= 0;
int y = 1;
int test = 0;
for ( int i=n;i>=2;i--)
{
test = x+y;
x=y;
y=test;
}
return test;
}
变种1
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
思路
从后往前想,每次下楼,都有两种选择,这个树形和斐波那契几乎一样
public int JumpFloor(int target) {
if (target<=2)
return target;
int x = 1;
int y = 1;
int test = 0;
for (int i = target;i>=2;i--)
{
test = x+y;
x=y;
y=test;
}
return test;
}
变种2
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
思路
其实,如果还按照刚才的想法就会变得很难,因为要有两层循环,而找到规律的话,只需要这样:
public int JumpFloorII(int target) {
return 1<<--target;
}
如果是一脉相承的思路的话:
public int JumpFloorII(int target) {
if(target == 0) {
return 0;
}
int[] dp = new int[target + 1];
dp[0] = 1;
dp[1] = 1;
for(int i = 2;i <= target;i++) {
dp[i] = 0;
for(int j = 0;j < i;j++) {
dp[i] += dp[j];
}
}
return dp[target];
}
收获
- 递归和循环的区别;递归还是用在比较简单或者真的无法用循环的时候,而且递归代码量很少,自然也就写起来很爽,但也容易看不懂