Python練習(一)斐波那契數列

2021-08-14 06:35:40 字數 2858 閱讀 7964

最近研究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 好吧,如果你願意,就算兩...