斐波那契數列介紹及Python中五種方法斐波那契數列
Q:斐波那契數列為什麼那麼重要,所有關於數學的書幾乎都會提到?
A:因為斐波那契數列在數學和生活以及自然界中都非常有用。
1. 斐波那契數列 概念引入
斐波那契數列(Fibonacci sequence),又稱黃金分割數列,因數學家列昂納多·斐波那契(Leonardoda Fibonacci)以兔子繁殖為例子而引入,故又稱為“兔子數列”。
數學上,斐波那契數列以遞迴的形式進行定義:
場景
先來開看看“兔子數列”以及其他數學應用場景!!
1. 1 兔子數列
一般而言,兔子在出生兩個月後,就有繁殖能力,一對兔子每個月能生出一對小兔子來。如果所有兔子都不死,那麼一年以後可以繁殖多少對兔子?
1.2 排列組合
有一段樓梯有10級臺階,規定每一步只能跨一級或兩級,要登上第10級臺階有幾種不同的走法?
更多數學方面知識,請戳:
斐波那契數列
…
2. 數列數學方法解答
2.1 兔子繁殖問題
斐波那契數列又因數學家列昂納多·斐波那契以兔子繁殖為例子而引入,故又稱為“兔子數列”。
一般而言,兔子在出生兩個月後,就有繁殖能力,一對兔子每個月能生出一對小兔子來。如果所有兔子都不死,那麼一年以後可以繁殖多少對兔子?
我們不妨拿新出生的一對小兔子分析一下:
第一個月小兔子沒有繁殖能力,所以還是一對
兩個月後,生下一對小兔對數共有兩對
三個月以後,老兔子又生下一對,因為小兔子還沒有繁殖能力,所以一共是三對
------
依次類推可以列出下表:
經過月數 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | … |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
幼仔對數 | 1 | 0 | 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 | … |
成兔對數 | 0 | 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 | 89 | |
總體對數 | 1 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 | 89 | 144 |
幼仔對數=前月成兔對數
成兔對數=前月成兔對數+前月幼仔對數
總體對數=本月成兔對數+本月幼仔對數
可以看出幼仔對數、成兔對數、總體對數都構成了一個數列。這個數列有關十分明顯的特點,那是:
前面相鄰兩項之和,構成了後一項。
2.2 排列組合
2.2.1 跨樓梯組合
有一段樓梯有10級臺階,規定每一步只能跨一級或兩級,要登上第10級臺階有幾種不同的走法?
這就是一個斐波那契數列:登上第一級臺階有一種登法;登上兩級臺階,有兩種登法;登上三級臺階,有三種登法;登上四級臺階,有五種登法……
1,2,3,5,8,13……所以,登上十級,有89種走法。
2.2.2 擲硬幣不連續情形
一枚均勻的硬幣擲10次,問不連續出現正面的可能情形有多少種?
答案是:
…
3. Python程式碼實現斐波那契數列
時間複雜度
空間複雜度
通過時間複雜度和空間複雜度評判程式碼的執行效率。
-
例如:從規模上來說,如果需要計算F(4)的值,需要進行9次元素操作
設T(n)為計算n的時間複雜度,那麼
一般情況,可以得出:粗略估算, ,上述程式碼求解F(n)的計算,它的時間複雜度是$O(2^n)
3.1 python特有寫法
列印正整數n
之內的斐波那契數列
# Python特有, 常規寫法
def fib(self, n):
a = 0
b = 1
while a <= n:
print(a, end=" ", flush=True)
a, b = b, a + b # python不借助變數交換兩數的值
fib(100) # 求n之內的斐波那契數列
3.2 遞迴
列印斐波那契數列前10位數字
# 遞迴
def fibonacci(i):
num_list = [0, 1]
if i < 2:
return num_list[i]
elif i >= 2:
return (fibonacci(i - 2) + fibonacci(i - 1))
print(fibonacci(10))
3.3 類物件
# 迭代的方式
class FibIterator(object):
"""斐波那契數列迭代器"""
def __init__(self, n):
"""
:param n: int, 指明生成數列的前n個數
"""
self.n = n
# current用來儲存當前生成到數列中的第幾個數了
self.current = 0
# num1用來儲存前前一個數,初始值為數列中的第一個數0
self.num1 = 0
# num2用來儲存前一個數,初始值為數列中的第二個數1
self.num2 = 1
def __next__(self):
"""被next()函式呼叫來獲取下一個數"""
if self.current < self.n:
num = self.num1
self.num1, self.num2 = self.num2, self.num1+self.num2
self.current += 1
return num
else:
raise StopIteration
def __iter__(self):
"""迭代器的__iter__返回自身即可"""
return self
if __name__ == '__main__':
fib = FibIterator(10)
for num in fib:
print(num, end=" ")
3.4 矩陣解決問題
從定義開始:
轉化為矩陣形式
可以得出:
我們設定