题目描述:
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
解题思路1:
一级台阶只有一种方法,两级台阶有两种方法,n级台阶第一次跳只有两种情况,可以拆分为第一次跳一级,有f(n-1)种方法,或第一次跳两级,有f(n-2)种方法,所以f(n)一共有f(n-1)+f(n-2)种方法,即同斐波那契数列原理相同。
可以使用递归,但是时间效率较低。
参考源码1:
class Solution {
public:
int jumpFloor(int number)
{
if(number <= 0) return 0;
if(number == 1) return 1;
if(number == 2) return 2;
return jumpFloor(number-1) + jumpFloor(number-2);
}
};
解题思路2:
使用循环,时间效率高。
参考源码2:
class Solution {
public:
int jumpFloor(int number)
{
if(number <= 0) return 0;
if(number == 1) return 1;
if(number == 2) return 2;
int lastlast = 1;
int last = 2;
int res = 0;
for(int i = 3;i <= number;i++)
{
res = lastlast + last;
lastlast = last;
last = res;
}
return res;
}
};
题目扩展1:
变态跳台阶:在青蛙跳台阶的问题中,如果把条件改成:一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级,此时该青蛙跳上一个n级的台阶总共有多少种跳法?
解题思路:
f1 = 1
f2 = f1 + 1 = 2
f3 = f2 + f1 + 1 = 2 + 2 = 4
f4 = f3 + f2 + f1 + 1 = 4 + 4 = 8
f5 = f4 + f3 + f2 + f1 + 1 = 16
所以,变态跳台阶仍旧是菲波那切数列,方法同跳台阶类似。
参考源码:
class Solution
{
public:
int jumpFloorII(int number)
{
if (number <= 0) return 0;
return pow(2, number-1);
}
};
//递归
class Solution
{
public:
int jumpFloorII(int number)
{
if (number <= 0) return 0;
if (number == 1) return 1;
if (number > 1)
{
return 2 * jumpFloorII(number - 1);
}
}
};
题目扩展2:
我们可以用2×1(图2.13的左边)的小矩形横着或者竖着去覆盖更大的矩形。请问用8个2×1的小矩形无重叠地覆盖一个2×8的大矩形(图2.13的右边),总共有多少种方法?
解题思路:
同样是进行数学建模:
f1 = 1,只有一个竖着放
f2 = f1 + 1 = 1+1 = 2,第一种一个竖着放,后面还有一个位置;第二种两个都横着放
f3 = f2 + f1 = 2+1 = 3,第一种一个竖着放,后面还有两个位置;第二种前面两个横着放,后面有一个位置
f4 = f3 + f2 = 3+2 = 5,第一种一个竖着放,后面还有三个位置,为f3;第二种前面两个横着放,后面还有两个位置,为f2
f5 = f4 + f3 = 5+3 = 8
所以,同样为斐波拉切数列。