算法积累-跳台阶问题
题目一:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法?
解析:
属于找规律的算法,设f(n)为跳n个台阶的跳法,从1开始找规律:
f(1) = 1 ;
f(2) = 2 ;
f(3) = 3 ;
f(4) = 5 ;
...
f(n) = f(n-1) = f(n-2) ;
可以看出是斐波拉契数序列,对于此题来说从n=3开始后每一个数的结果等于前两个的结果之和.可以用递归或者迭代做,因为递归包含很多重复运算,所以用迭代效率会好一些.
递归方法
public int Jump(int n) {
if (n <= 0) {
return -1;
}
switch (n) {
case 1:
return 1;
case 2:
return 2;
default:
return Jump(n - 1) + Jump(n - 2);
}
}
迭代方法
public int Jump1(int n) {
if (n <= 2) {
return n;
}
int fron = 1;
int nex = 2;
int sum = 0;
for (int i = 3; i <= n; i++) {
sum = fron + nex;
fron = nex;
nex = sum;
}
return sum;
}
题目二:一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法?
此题被叫做疯狂跳台阶,在普通跳台阶的基础上面需要加深一些理解
此题有多种理解方式:
第一种:
f(1) = 1 ;
f(2) = f(2 - 1 ) + f(2 - 2 ) = 1 + 1 =2; //第一次跳一阶后剩下的台阶数跳的方法+第一次跳2阶剩下的台阶跳的方法
f(3) = f(3 - 1 ) + f(3 - 2 ) + f ( 3 - 3 ) = f(2) + f (1) +1 = 4 ; //意思类似
f(4) = f(4 - 1 ) + f( 4 - 2 ) + f (4 - 3 ) + f( 4 - 4 ) = f(3 + f(2) + f(1) + 1 = 8 ;
...
f(n) = f(n-1)+f(n-2)+f(n-3)+...+f(n-n);
然后可以发现规律:f(n) = 2*f(n-1) ;
代码为(当然也可以使用迭代方法):
if (n == 1) {
return 1;
}
return Jump1(n - 1) * 2
第二种理解:每一个台阶都有两种状态,除了最后一个台阶必须跳,跳和不跳两种状态,则方法为f(n) = 2^(n-1);
代码为:
public int Jump2(int n) {
return (int) Math.pow(2, n - 1);
}
看评论学到另外一种方式,就一行代码,如下:
个人觉得是第二种方法的另外一种写法,略微看不懂…
public int Jump3(int n) {
return 1 << --n;
}