算法 Fibonacci 数列的一类问题(一)

Fibonacci 是算法中的基础问题。还有一些问题本质是Fibonacci 问题,也就是递归问题。在此我们一并总结探讨。

1.  Fibonacci 数列

问题描述:

数列位数序号       1,2,3,4,5,6,...

Fibonacci 数列     1,1,2,3,5,8,...

Fibonacci 数列的性质很简单,就是从第三位起,数列中每一项等于前两项的和,如 第4项 = 第3项 + 第2项。

题目的要求是,输入一个整数n,输出Fibonacci 数列的第n项(从0开始,第0项为0)。

 

解决思路:

函数中递归调用自己,求出最终解。

def Fibonacci(n):
    if n < 2:
        return n
    else:
        return Fibonacci(n-1) + Fibonacci(n-2)

 

2.  初级青蛙跳

问题描述:

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

 

解决思路:

乍一看,问题复杂。我们不妨做一个带入:

台阶跳法共计跳法
11{1}
22{1,1}    {2}
33{1,1,1}    {1,2}    {2,1}
45{1,1,1,1}    {1,1,2}    {1,2,1}    {2,1,1}    {2,2}

 

我们观察表的前2列,很容易得到规律,这是个Fibonacci 问题。从第3阶开始,第n阶 = 第n-2阶 + 第n-1阶

我们依然用递归的思路写出代码

def jumpFloor(n):
    if n < 3:
        return n
    else:
        return jumpFloor(n-2) + jumpFloor(n-1)

 

3.  变态青蛙跳

问题描述:

一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。 

 

解决思路:

这似乎比初级青蛙跳复杂了很多,我们依然带入寻找规律:

台阶跳法共计跳法
11{1}
22{1,1}    {2}
34{1,1,1}    {1,2}    {2,1}    {3}
48

{1,1,1,1}    {1,1,2}    {1,2,1}    {2,1,1}    {1,3}    {3,1}    {2,2}   

{4}

我们进一步对跳法进行抽象。并令跳F(0) = 1,这指的是剩下0个台阶时只有1种跳法,即直接跳n阶。我们可以这样理解,从第2阶开始,假设第1次跳1阶,剩下的1阶有F(1)中跳法;假设第1次跳2阶,剩下的0阶有F(0)中跳法。同理,第3阶,假设第1次跳1阶,剩下的2阶有F(2)中跳法;假设第1次跳2阶,剩下的1阶有F(1)中跳法;假设第1次跳3阶,剩下的0阶有F(0)中跳法。

F(0) = 1

F(1) = 1

F(2) = F(1) + F(0) =2

F(3) = F(2) + F(1) + F(0) = 4

F(4) = F(3) + F(2) + F(1) + F(0) = 8

 进而得到

F(n-1) = \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ F(n-2) + F(n-3) +...+ F(1) + F(0)

F(n) \ \ \ \ \ = F(n-1) + F(n-2) + F(n-3) +...+ F(1) + F(0)

令两式相减得到

F(n) = 2F(n-1)

如此,递归就可以很好的解决这个问题。

def jumpFloor(n):
    if n < 2:
        return n
    else:
        return 2 * jumpFloor(n-1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值