青蛙跳台阶问题
从自己的博客转载过来的。
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。 公式不能在hexo上显示出来
解题思路:函数思想,把n阶台阶的跳法看成是关于n的函数 f(n)。当n>2的时候:
假设第一次跳一个台阶,那么还剩n-1个台阶需要跳,也就是还有f(n-1)的跳法。
假设第一次跳两个台阶,那么还剩n-2个台阶需要跳,也就是还有f(n-2)的跳法
所以n阶的跳法总共有f(n-1) + f(n-2) 种,也就是 f(n) = f(n-1) +f(n-2)。
所以函数就是 :
f
(
n
)
=
{
0
n=0
1
n=1
2
n=2
f
(
n
−
1
)
+
f
(
n
−
2
)
n>2
f(n)= \begin{cases} 0& \text{n=0}\\ 1& \text{n=1}\\ 2& \text {n=2}\\ f(n-1)+f(n-2)& \text {n>2} \end{cases}
f(n)=⎩⎪⎪⎪⎨⎪⎪⎪⎧012f(n−1)+f(n−2)n=0n=1n=2n>2
也就是一个斐波那契数列,代码也就比较简单了。参考斐波那契数列的解法:
https://github.com/BraveY/Coding/blob/master/剑指offer/Fibonacci.cc
代码为:
class Solution {
public:
int jumpFloor(int number) {
int result[3] = {0,1,2};
if(number<3) return result[number];
int fib_one = result[1];
int fib_two = result[2];
int fib;
for(int i=3; i<=number; i++){
fib = fib_one + fib_two;
fib_one = fib_two;
fib_two = fib;
}
return fib;
}
};
变种题目:
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
思路也是一样的:第一次跳1级台阶,则有f(n-1)的解法,第一次跳2级台阶,则有f(n-2)的解法,第一次跳n-1级台阶,则有f(2)的解法, 第一次跳n级台阶则还有一种解法。用f(0)表示第一次跳n级的情况,f(0)=1。
归纳成函数就是:
f
(
n
)
=
{
1
n=0
1
n=1
f
(
n
−
1
)
+
f
(
n
−
2
)
.
.
.
+
f
(
1
)
+
f
(
0
)
n>1
f(n)= \begin{cases} 1& \text{n=0}\\ 1& \text{n=1}\\ f(n-1)+f(n-2)...+f(1)+f(0)& \text {n>1} \end{cases}
f(n)=⎩⎪⎨⎪⎧11f(n−1)+f(n−2)...+f(1)+f(0)n=0n=1n>1
所以代码为:
class Solution {
public:
int jumpFloorII(int number) {
vector<int> result;
result.push_back(1); // f(0) =1 ;
for(int i=1; i<=number; i++){
int sum = 0;
for(int j=0; j<i; j++){ // f(n)=f(n-1)+f(n-2)+...f(1)+f(0)
sum += result[j];
}
result.push_back(sum);
}
return result[number];
}
};
另一个斐波那契数列数列问题:
矩形覆盖
我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
最开始的时候没有想清楚,以为不是斐波那契数列。
思路:
同样的方法为n的函数:f(n); 对于n=1的情况,只能竖着放:所以f(1)=1; n=2的时候,竖着放之后就变成了f(1)种方法,横着放的时候只有一种,总共有两种,所以f(2)=2;
所以函数为:
f
(
n
)
=
{
0
n=0
1
n=1
2
n=2
f
(
n
−
1
)
+
f
(
n
−
2
)
n>2
f(n)= \begin{cases} 0& \text{n=0}\\ 1& \text{n=1}\\ 2& \text {n=2}\\ f(n-1)+f(n-2)& \text {n>2} \end{cases}
f(n)=⎩⎪⎪⎪⎨⎪⎪⎪⎧012f(n−1)+f(n−2)n=0n=1n=2n>2
因此代码也是同第一个青蛙跳台阶一样的。
代码:
//https://www.nowcoder.com/practice/72a5a919508a4251859fb2cfb987a0e6?tpId=13&tqId=11163&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
class Solution {
public:
int rectCover(int number) {
int result[3] = {0,1,2};
if(number<3) return result[number];
int fib_one = result[1];
int fib_two = result[2];
int fib;
for(int i=3; i<=number; i++){
fib = fib_one + fib_two;
fib_one = fib_two;
fib_two = fib;
}
return fib;
}
};
总结
总结一下,对于斐波那契数列问题思路都是一样:
- 输出是输入的函数, f(n)
- 考虑第一次是如何选择的,就可以把问题给切分出来了。
本文探讨了青蛙跳台阶问题及其变种,包括跳上n级台阶的不同跳法,这个问题可以用斐波那契数列来解决。文章提供了相关代码实现,并通过矩形覆盖问题进一步阐述了斐波那契数列的应用。
1万+

被折叠的 条评论
为什么被折叠?



