TOP

Python算法 - 递归精解 - 斐波那契数列问题

递归原理

形式 -  函数内部调用函数本身 

- 函数之间的传递参数

- 自动完成

终止 - 递归停止的条件

斐波那契数列

 此案例可以延申很多。 类似兔子繁殖问题, 上楼梯问题等等

递归的方式实现

递归的方式是逆向的, 往后递归倒最底层的 1+1 上再一层一层返回到低 k 层上的进行累加

原理图示

递的过程中, 相当于把任务分级,  f3 因为 达到终止条件后 计算得到 2, 于是才有精力在计算 f2

于是基于此流程再依次重复计算 f3, f4

由此可见里面存在大量的重复计算的过程, 而且重复的次数随着k的增加会更快程度的增加

而非递归的方式就不会有这种问题, 不论 k 你怎么取时间都较为稳定

代码实现

# 1 1 2 3 5 8 13 21 ....

def fib_test(k):
    # 求解第 k 个数的值
    assert k > 0, u"k 必须大于0"
    if k in [1, 2]:
        return 1
    return fib_test(k - 1) + fib_test(k - 2)


if __name__ == '__main__':
    print fib_test(5)  # 5
    print fib_test(7)  # 13

非递归的方式实现

非递归方式是正向, 从1+1 开始通过更新 k-1 和 k-2 实现

代码实现

# 1 1 2 3 5 8 13 21 ....

def fib_test(k):
    # 求解第 k 个数的值
    assert k > 0, u"k 必须大于0"
    if k in [1, 2]:
        return 1
    k_1 = 1
    k_2 = 1
    for i in range(3, k+1):
        # 便于理解的形式
        # tmp = k_1 
        # k_1 = k_1 + k_2
        # k_1 = tmp
        k_1, k_2 = k_1 + k_2, k_1

    return k_1


if __name__ == '__main__':
    print fib_test(6)  # 8
    print fib_test(7)  # 13

斐波那契问题其他类型 - 爬楼梯

反向思考, 对于最后一层台阶来说,  有几种可能性爬上来? 

1. 从倒数第二层台阶(k-1) 爬一级到最后一层台阶

2. 从倒数第三层台阶(k-2) 爬两级到最后一层台阶

同理对于倒数第二层台阶来说, 有几种可能性爬上来? 

1. 从倒数第三层台阶(k-1) 爬一级到最后一层台阶

2. 从倒数第四层台阶(k-2) 爬两级到最后一层台阶

由此可见还是满足公式

f(k) = f(k-1) + f(k-2)    爬上每一层台阶的可能性等于前一层和前两次的可能加和

且 f(1) = 1 f(2) = 1  倒数第二和倒数第三爬到最后一层的可能性都为 1 

斐波那契问题其他类型 - 生兔子

1  2 (1月兔)  = 2

2  2 (1月兔)  = 2 

3  2 (1月兔) + 2(1月兔生- 3月兔)   = 4

4  2 (1月兔)  + 2(3月兔)  + 2(1月兔生- 4月兔)   = 6

5  2 (1月兔)  + 2(3月兔)  + 2(4月兔)  + 2(1月兔生- 5月兔)   +  2(3月兔生- 5月兔)    =8

6 ......  

上述规律可以看出,  f(k)  = f(k-1)  + f(k-3)    因为是一对兔子生一对兔子

所以每个月的增量都应该是前前一个月的兔子数量 (兔子隔月生)

且满足 f(1)  = 2 , f(2)  = 2, 初始只有一对兔子, 第二个月每生出来也只有一对兔子

 

posted @ 2020-03-31 16:23  羊驼之歌  阅读(985)  评论(0编辑  收藏  举报