1. 斐波那契數列應用普遍,對此數列的更好理解有助於咱們算法的更進一步,並下降程序的時間複雜度,提升運行效率.css
2. 斐波那契數列的應用(4種):html
2.1 排列組合----經典例子:爬樓梯算法
""" 有一段樓梯有10級臺階,規定每一步只能跨一級或兩級,要登上第10級臺階有幾種不一樣的走法? 這就是一個斐波那契數列:登上第一級臺階有一種登法;登上兩級臺階,有兩種登法;登上三級臺階,有三種登法;登上四級臺階,有五種登法…… 1,2,3,5,8,13……因此,登上十級,有89種走法。 相似的,一枚均勻的硬幣擲10次,問不連續出現正面的可能情形有多少種? 答案是(1/√5)*{[(1+√5)/2]^(10+2) - [(1-√5)/2]^(10+2)}=144種。 求遞推數列a⑴=1,a(n+1)=1+1/a(n)的通項公式 由數學概括法能夠獲得:a(n)=F(n+1)/F(n),將斐波那契數列的通項式代入,化簡就得結果。 """
2.2 兔子數列----兔子繁殖問題npm
""" 斐波那契數列又因數學家列昂納多·斐波那契以兔子繁殖爲例子而引入,故又稱爲「兔子數列」。 通常而言,兔子在出生兩個月後,就有繁殖能力,一對兔子每月能生出一對小兔子來。若是全部兔子都不死,那麼一年之後能夠繁殖多少對兔子? 咱們不妨拿新出生的一對小兔子分析一下: 第一個月小兔子沒有繁殖能力,因此仍是一對 兩個月後,生下一對小兔對數共有兩對 三個月之後,老兔子又生下一對,由於小兔子尚未繁殖能力,因此一共是三對 幼仔對數=前月成兔對數 成兔對數=前月成兔對數+前月幼仔對數 整體對數=本月成兔對數+本月幼仔對數 能夠看出幼仔對數、成兔對數、整體對數都構成了一個數列。這個數列有關十分明顯的特色,那是:前面相鄰兩項之和,構成了後一項。 這個數列是意大利中世紀數學家斐波那契在<算盤全書>中提出的,這個級數的通項公式,除了具備a(n+2)=an+a(n+1)的性質外,
還能夠證實通項公式爲:an=(1/√5)*{[(1+√5)/2]^n-[(1-√5)/2]^n}(n=1,2,3,...) """
2.3 數列與矩陣(如今的我暫時用不上)app
""" 對於斐波那契數列一、一、二、三、五、八、1三、……。有以下定義 F(n)=F(n-1)+F(n-2) F(1)=1 F(2)=1 對於如下矩陣乘法 F(n+1) = (1,1 ) (F(n),F(n-1))T F(n) =(1,0 ) (F(n),F(n-1))T 它的運算就是右邊的矩陣 (1,1)乘以矩陣(F(n),F(n-1)),右邊的矩陣(1,0 ) 乘以矩陣(F(n),F(n-1)),獲得: F(n+1)=F(n)+F(n-1) F(n)=F(n) 可見該矩陣的乘法徹底符合斐波那契數列的定義 設矩陣A=第一行(1,1)第二行(1,0) 迭代n次能夠獲得:F(n+1) =A^(n) *( F(2),F(1))T= A^(n)*(1,1)T 這就是斐波那契數列的矩陣乘法定義。 另矩陣乘法的一個運算法則A^n(n爲偶數) = A^(n/2)* A^(n/2),這樣咱們經過二分的思想,能夠實現對數複雜度的矩陣相乘。 所以能夠用遞歸的方法求得答案。 數列值的另外一種求法: F(n) = [ (( sqrt ( 5 ) + 1 ) / 2) ^ n ] 其中[ x ]表示取距離 x 最近的整數。 """
2.4 斐波那契弧線(暫時用不上)函數
""" 斐波那契弧線,也稱爲斐波那契扇形線。第一,此趨勢線以二個端點爲準而畫出,例如,最低點反向到最高點線上的兩個點。
而後經過第二點畫出一條「無形的(看不見的)」垂直線。而後,從第一個點畫出第三條趨勢線:38.2%, 50%和61.8%的無形垂直線交叉。 斐波納契弧線,是潛在的支持點和阻力點水平價格。斐波納契弧線和斐波納契扇形線經常在圖表裏同時繪畫出。支持點和阻力點就是由這些線的交匯點得出。 要注意的是弧線的交叉點和價格曲線會根據圖表數值範圍而改變,由於弧線是圓周的一部分,它的造成老是同樣的。 """
繪製圖形如右圖:oop
3. 如何用代碼求斐波那契數列(4種方法):spa
1).遞歸 效率最低,時間複雜度時間複雜度O(1.618^n).net
def fib_recur(n): assert n >= 0, "n > 0" if n <= 1: return n return fib_recur(n-1) + fib_recur(n-2) for i in range(1, 20): print(fib_recur(i), end=' ')
PS:遞歸 進階版code
使用lru_cache可減小重複計算.
from functools import lru_cache class Solution: @lru_cache(10**8) def climbStairs(self, n): """ :type n: int :rtype: int """ if n == 1: return 1 elif n == 2: return 2 else: return self.climbStairs(n - 1) + self.climbStairs(n - 2)
2)循環 也是遞推法,遞增法,時間複雜度O(n)
def fib_loop(n): a, b = 0, 1 for i in range(n+1): a, b = b, a+b return a for i in range(20): print(fib_loop(i), end=' ')
3)生成器
def fib_loop_while(max): a, b = 0, 1 while max > 0: a, b = b, a+b max -= 1 yield a for i in fib_loop_while(10): print(i)
4)類實現內部魔法方法
class Fibonacci(object): """斐波那契數列迭代器""" def __init__(self, n): """ :param n:int 指 生成數列的個數 """ self.n = n # 保存當前生成到的數據列的第幾個數據,生成器中性質,記錄位置,下一個位置的數據 self.current = 0 # 兩個初始值 self.a = 0 self.b = 1 def __next__(self): """當使用next()函數調用時,就會獲取下一個數""" if self.current < self.n: self.a, self.b = self.b, self.a + self.b self.current += 1 return self.a else: raise StopIteration def __iter__(self): """迭代器的__iter__ 返回自身便可""" return self if __name__ == '__main__': fib = Fibonacci(15) for num in fib: print(num)
5) 矩陣 時間複雜度爲 O(log n) (矩陣的話不太好理解,須要先提升數學素養)
import numpy def fib_matrix(n): res = pow((numpy.matrix([[1, 1], [1, 0]])), n) * numpy.matrix([[1], [0]]) return res[0][0] for i in range(10): print(int(fib_matrix(i)), end=' ') ### 2 # 使用矩陣計算斐波那契數列 def Fibonacci_Matrix_tool(n): Matrix = npmpy.matrix("1 1;1 0") # 返回是matrix類型 return pow(Matrix, n) # pow函數速度快於 使用雙星好 ** def Fibonacci_Matrix(n): result_list = [] for i in range(0, n): result_list.append(numpy.array(Fibonacci_Matrix_tool(i))[0][0]) return result_list # 調用 Fibonacci_Matrix(10)
PS:由於冪運算可使用二分加速,因此矩陣法的時間複雜度爲 O(log n)
用科學計算包numpy來實現矩陣法 O(log n)
6) 公式求解 時間複雜度O(1)
首先,列出公式:
from math import sqrt def fibonacci(n): s = int(1/sqrt(5)*(pow(((1+sqrt(5))/2),n)-pow(((1-sqrt(5))/2),n))) return s for i in range(10): print(fibonacci(i))
轉自:https://baike.baidu.com/item/斐波那契數列/99145?fr=aladdin#5
https://blog.csdn.net/JIEJINQUANIL/article/details/52422141
https://www.cnblogs.com/panlq/p/9307203.html
來自LeetCode的wikizero的回答