最近研究python基礎,再次對斐波那契數列進行再度擴充套件研究。之前的實現只針對c#。
二,斐波那契數列剖析
斐波那契數列邏輯很簡單如圖所示:
問題的關鍵在於當輸入的元素下標大於1時如何呈現。0和1 利用列舉就可以直接輸出。大於1的情況我們有如下幾種方式。
三,遞迴演算法
遞迴演算法,不停地迭代呼叫直至返回最底層的值。耗用的時間複雜度相對較高 o(2^n)
class fibonacci:
def __init__(self):
pass
def fibonacci(self, n) -> int:
# write your code here
if n == 0:
return 0
if n == 1:
return 1
if n > 1:
return self.fibonacci(n - 2) + self.fibonacci(n - 1)
例如我們呼叫元素下標為5的值。
fibonacci(5)
-> fibonacci(4)+fibonacci(3)
->fibonacci(3)+fibonacci(2)+fibonacci(2)+fibonacci(1)
->fibonacci(2)+fibonacci(1)+fibonacci(1)+fibonacci(0)+fibonacci(1)+fibonacci(0)+1
->fibonacci(1)+fibonacci(0)+1+1+0+1+0+1
->1+0+1+1+0+1+0+1
->5
因為遞迴運算時間複雜度相對較高。我們採用非遞迴方式來計算數列。時間複雜度o(n) 空間複雜度 o(n)
def nonrecursivefibonacci(self, n) -> int:
# 首先定義第0個和第1個陣列
fibval = [0, 1];
# 迴圈體變數 初始化2開始
count = 2;
# 目的是為了往陣列裡插入最新的數值 也就是 有且僅當 陣列長度小於或者等於輸入的元素個數 進入迴圈體
while len(fibval) <= n:
# 迴圈變數每次會累加 當累加到輸入元素個數 即進入邏輯運算
if count <= n:
pre = fibval[count - 1]
nex = fibval[count - 2]
# 把陣列的前兩個元素相加 追加的陣列末尾
# 並且把迴圈變數累加
count = count + 1
# 獲取陣列長度
length = len(fibval)
# 因為陣列下標是0開始即返回長度-1的元素即為所得
return fibval[length - 1]
上述方法採用陣列容器來實現。以下採用純變數迭代式方法實現。時間複雜度 o(n) 空間複雜度o(1)
def nonrecursivefibonacci2(self, n) -> int:
if n < 2 and n >= 0:
return n
# 首先定義第乙個元素和第二個元素 以及預設返回的值val 暫且初始化為0
first = 0;
second = 1;
val = 0;
# 迴圈體變數 初始化2開始
index = 2;
# 有且僅當 陣列長度小於或者等於輸入的元素個數 進入迴圈體
while index <= n:
# 迭代值新值變數 為 第乙個元素和第二個元素之和
val = first + second
# 置換第一元素
first = second
# 置換第二元素
second = val
# 迴圈變數累加
index = index + 1
return val
兩種演算法邏輯運算方式一樣,只是採取的容器不同。陣列容器便於理解,變數迭代省空間。但是對於優化演算法的最基本理念:「犧牲空間複雜度,來提高時間複雜度。」這一點 採用陣列容器更易於理解。
五,尾遞迴演算法
顧名思義,
尾遞迴就是從最後開始計算, 每遞迴一次就算出相應的結果, 也就是說, 函式呼叫
出現在呼叫者函式的尾部, 因為是尾部, 所以根本沒有必要去儲存任何區域性變數
. 直接讓被呼叫的函式返回時越過呼叫者, 返回到呼叫者的呼叫者去。尾遞迴就是把當前的運算結果(或路徑)放在引數裡傳給下層函式
,深層函式所面對的不是越來越簡單的問題,而是越來越複雜的問題,因為引數裡帶有前面若干步的運算路徑。
尾遞迴是極其重要的,不用尾遞迴,函式的堆疊耗用難以估量,需要儲存很多中間函式的堆疊。比如f(n, sum) = f(n-1) + value(n) + sum; 會儲存n個函式呼叫堆疊,而使用尾遞迴f(n, sum) = f(n-1, sum+value(n)); 這樣則只保留後乙個函式堆疊即可,之前的可優化刪去。
我們來改造一下之前的遞迴演算法,這裡只是提出這樣乙個概念。(並不能提高運算速度,***來打我啊!)
def fibonacci(self, n) -> int:
# write your code here
if n < 2:
return n
return self.fibonacci(n - 2) + self.fibonacci(n - 1)
斐波那契數列 斐波那契數列python實現
斐波那契數列 fibonacci sequence 又稱 分割數列 因數學家列昂納多 斐波那契 leonardoda fibonacci 以兔子繁殖為例子而引入,故又稱為 兔子數列 指的是這樣乙個數列 1 1 2 3 5 8 13 21 34 在數學上,斐波納契數列以如下被以遞推的方法定義 f 1 ...
Python小練習 斐波那契數列
斐波那契數列 fibonacci sequence 又稱 分割數列 因數學家列昂納多 斐波那契 leonardoda fibonacci 以兔子繁殖為例子而引入,故又稱為 兔子數列 指的是這樣乙個數列 1 1 2 3 5 8 13 21 34 這個數列從第3項開始,每一項都等於前兩項之和。下面分享兩...
python 斐波那契數列
用python寫斐波那契數列當然大家都寫的出來。當時如果用一行 寫呢。本來沒有打算用一行 寫的。後來看到有用一行 寫階乘的。reduce lambda x,y x y,i for i in range 1,n 1 當然在這之前需要 from functools import 好吧,如果你願意,就算兩...