青蛙跳台阶问题是一个简单的动态规划问题。
问题1:普通跳台阶
一只青蛙可以一次跳 1 级台阶或者一次跳 2 级台阶,例如:
- 跳上第 1 级台阶只有一种跳法:直接跳 1 级即可。
- 跳上第 2 级台阶有两种跳法:每次跳 1 级,跳两次;或者一次跳 2 级。
问要跳上第 n 级台阶有多少种跳法?
很多人喜欢正向思考,使用暴力求解,但往往这是一个很复杂的问题。我们可以反过来思考:
如果我们要跳上第
我们令
是不是很熟悉,它不就是斐波那契数列吗,代码就很简单啦:
int jumpFloor(int number) {
int g = 1, f = 2;
while (number-- > 1) {
f += g;
g = f - g;
}
return g;
}
问题2:变态跳台阶
变态跳台阶问题是这样的:如果青蛙可以一次跳 1 级,也可以一次跳 2 级,一次跳 3 级,…,一次跳
n
级。问要跳上第
同样的,我们采用逆向思维,将问题改为:跳上第 n 级台阶该怎么跳?答案如下:
要跳上第
同时, f(n−1) 也可以表示如下:
所以,由上面两个公式可知:
即:
因为 f(1)=1 ,所以 f(n)=2n−1 。
代码如下:
int square(int a) { return a * a; }
int power2(int n) { // 计算2的n次方
if (0 == n) return 1;
return n % 2 ? square(power2(n>>1))<<1 : square(power2(n>>1));
}
int jumpFloorII(int number) {
return power2(number - 1);
}