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, 初始只有一對兔子, 第二個月每生出來也只有一對兔子

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM