遞迴演算法大家應該都不陌生吧,其實最開始遇見遞迴應該是在數學課上,類似於f(x)=f(x-1)+f(x+1),f(1)=1,f(2)=4,f(3)=3這種數學題大家應該見過不少,其實思想就是層層遞迴,最終將目標值用f(1),f(2),f(3)表示。
之前做個乙個需求,需要實現類似作業系統資料夾的功能,我們用mysql資料庫記錄資料,表字段有4列,分別是id,index_name,pid,is_directory,index_name記錄檔案或檔案的名字,pid記錄它的父級id,is_directory標記它是檔案還是資料夾。記錄被存下以後,就涉及到取資料的問題了,我們前端需要的目標資料結構是這樣的
[,,
,
,...]
有點類似linux系統的tree命令。
第一版**是這樣的:
tree =
def gettree(pid):
return
for
index
in
childindexes:
if
len(tree) == 0:
if
)
gettree(index.
id
)
else
:
)
else
:
for
item
in
tree:
if
item[
'id'
] == index.
id
if
'id'
:index.
id
,
'name'
:
item[
'name'
]+index.index_name+
'/'
})
else
:
(
)
大概看一下這個演算法的時間複雜度,第一層的遍歷時間複雜度是n,第二層遍歷的時間複雜度是n,內層的時間複雜度是o(n^2),再加上遞迴,最後的時間複雜度是o(2^n*n^2),這個演算法可見很粗糙,假如遞迴深度到是100,最後執行效率簡直會讓人頭皮發麻。接下來我們考慮一下如何優化。
第二版**:
tree =
def gettree(pid,path=
'./'
):
return
for
index
in
childindexes:
if
len(tree) == 0:
if
'id'
:index.
id
,
'name'
:path+index.index_name+
'/'
})
gettree(index.
id
,
path+index.index_name+
'/'
)
else
:
'id'
:index.
id
,
'name'
:path+index.index_name})
else
:
if
'id'
:index.
id
,
'name'
:path+index.index_name+
'/'
})
else
:
'id'
:index.
id
,
'name'
:path+index.index_name})
我們用變數儲存每一次的path,這次我們看看時間複雜度是多少。第一層遍歷時間複雜度是o(n),加上遞迴,最後的時間複雜度是o(2^n*n),不算太理想,最起碼比第一次好點。
再看看乙個面試的常見的題目,斐波拉契數列,n=1,1,3,5,8,13...,求第n位是多少?
一看首先就想到了遞迴的方式:
def fibsquence(n):
if
n
in
(1,2):
return
fibsquence(n-1)+ fibsquence(n-2)
這個演算法的時間複雜度是o(2^n),關於時間複雜度具體看呼叫次數便能明白。我們考慮一下如何優化,比如求n=3是,需要先求n=2,n=1,但是最開始n=1,n=2已經求過,多了兩步重複計算。
下面是優化的**:
fibmap =
def fibsquence(n):
else
:
result = fibsquence(n-1)+ fibsquence(n-2) fibmap.update()
return
result
我們用map報存中間值,map是基於hash實現的,時間複雜度是o(1),這樣這個演算法的時間複雜度就是o(n)。
但是事實上這個問題大可不必用遞迴方式求解
fibmap =
def fibsquence(n):
else
:
for
i
in
range(3,n+1):
fibmap.update()
return
fibmap[n]
這樣我們只用一次遍歷,便可以求出目標值。
遞迴演算法的優化大概就是避免重複運算,將中金狀態儲存起來,以便下次使用,從結構上來看,是將時間複雜度轉換為空間複雜度來解決。遞迴演算法的效率其實是非常低的,能不用遞迴就盡量不用遞迴;當然了也要具體問題具體對待,比如說開始提到我做的專案遇到的問題,不用遞迴我還真想不出其他更好的方式解決。
宜信技術學院
遞迴演算法時間複雜度
開篇前言 為什麼寫這篇文章?筆者目前在學習各種各樣的演算法,在這個過程中,頻繁地碰到到遞迴思想和分治思想,驚訝於這兩種的思想的偉大與奇妙的同時,經常要面對的乙個問題就是,對於乙個給定的遞迴演算法或者用分治思想縮小問題規模的演算法,如何求解這個演算法的時間複雜度呢?在google過很多的博文後,感覺這...
遞迴演算法時間複雜度
求遞迴演算法時間複雜度 遞迴樹 遞迴演算法時間複雜度的計算方程式乙個遞迴方程 在引入遞迴樹之前可以考慮乙個例子 t n 2t n 2 n2迭代2 次可以得 t n n2 2 2t n 4 n 2 2 還可以繼續迭代,將其完全展開可得 t n n2 2 n 2 2 2 n 22 2 2 n 23 2 ...
遞迴演算法的時間複雜度
遞迴演算法大家應該都不陌生吧,其實最開始遇見遞迴應該是在數學課上,類似於f x f x 1 f x 1 f 1 1,f 2 4,f 3 3這種數學題大家應該見過不少,其實思想就是層層遞迴,最終將目標值用f 1 f 2 f 3 表示。之前做個乙個需求,需要實現類似作業系統資料夾的功能,我們用mysql...