题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
对问题的理解:n级台阶,一次可以跳1级,也可以跳2级。如果第一次跳了1级,那么剩下n-1级台阶,n-1级台阶的跳法有f(n-1);如果第一次跳了2级台阶,剩下n-2级台阶,剩下的n-2级台阶的跳法有f(n-2).
f(1) = 1;
f(2) = 2;
f(n) = f(n-1) + f(n-2);
那么可以把问题当成斐波那契数列来解决。
有3中方式。
1.递归方式
public int Fibonacci(int n) {
if(n==1){
return 1;
}
if(n==2){
return 2;
}
return Fibonacci(n-2)+Fibonacci(n-1);
}
递归方式需要重复的计算,时间复杂度O(2^n),空间复杂度O(n)
2.存储方式
public int Fibonacci(int n) {
if(n==1){
return 1;
}
if(n==2){
return 2;
}
int[] ints = new int[n+1];
ints[1] = 1;
ints[2] = 2;
for(int i=2;i<n+1;i++){
ints[i] = ints[i-1]+ints[i-2];
}
return ints[n];
}
时间复杂度O(n),空间复杂度O(n)
3.简化存储方式
public int Fibonacci(int n) {
//由于我们每次只用到了相近n的两个数,所以只保存这两个数
if(n==1){
return 1;
}
if(n==2){
return 2;
}
int a = 1;
int b = 2;
int c = 0;
int i = 3;
while(i<=n){
c = a + b;
a = b;
b = c;
i++;
}
return c;
}
由于计算n的话,只需要n-1,和n-2,所以可以在每次计算完之后值存储n-1,n-2。
时间复杂度:O(n)
空间复杂度:O(1)
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
分析:
f(1) = 1;
f(2) = f(2-1) + f(2-2);
f(3) = f(3-1) + f(3-2) + f(3-3);
......
f(n) = f(n-1) + f(n-2) + f(n-3) + ... + f(n-(n-1))+ f(n-n);
public int JumpFloorII(int target) {
if(target == 1){
return 1;
}
if(target == 2){
return 2;
}
int res = 0;
int[] ints = new int[target+1];
ints[1] =1;
ints[2] =2;
ints[0] = 1;
for(int i=3;i<target+1;i++){
for(int j=i;j>0;j--){
ints[i] += ints[i-j];
}
}
return ints[target];
}
题目描述
我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
分析:
如果,总的容器是2*n,填充板是2*1,n是不确定的,从如图所示的顶部开始填充,
f(1) = 1;(2*1) 竖着
f(2) = 2; (2*2) 横着放和竖着放两种,
f(3) =4 ;(2*3) 第3行横着放,剩下两行f(n-1)=f(2) = 3;竖着放,还剩1行f(n-2)=f(1)=1;
f(4) = ;(2*4)第n行横着放,f(n-1)=?;竖着放,f(n-2)=? f(n) = f(n-1)+f(n-2);
注意:外部盒子长度只有2(假设2为长,n为宽), 所以不用考虑长上面的变化,只需要考虑n上面的变化。
所以还是斐波那契数列。