遞歸和分治區別


分治法的基本思想:將一個規模為n的問題分解為k個規模較小的子問題,這些子問題互相獨立且與原問題相同。遞歸地解這些問題,然后將各個子問題的解合並成原問題的解。

分治法所能解決的問題一般具有以下幾個特征:

 

該問題的規模縮小到一定的程度就可以容易地解決;因為問題的計算復雜性一般是隨着問題規模的增加而增加,因此大部分問題滿足這個特征。

該問題可以分解為若干個規模較小的相同問題,即該問題具有最優子結構性質這條特征是應用分治法的前提,它也是大多數問題可以滿足的,此特征反映了遞歸思想的應用

利用該問題分解出的子問題的解可以合並為該問題的解;能否利用分治法完全取決於問題是否具有這條特征,如果具備了前兩條特征,而不具備第三條特征,則可以考慮貪心算法或動態規划。

該問題所分解出的各個子問題是相互獨立的,即子問題之間不包含公共的子問題。這條特征涉及到分治法的效率,如果各子問題是不獨立的,則分治法要做許多不必要的工作,重復地解公共的子問題,此時雖然也可用分治法,但一般用動態規划較好(例如記憶化搜索是分治轉化為動歸的一個經典, 要注意)。

分治法的復雜性分析:

 

一個分治法將規模為n的問題分成k個規模為n/m的子問題去解時間復雜度多為O(n)

 

遞歸的優點:結構清晰,可讀性強,而且容易用數學歸納法來證明算法的正確性,因此它為設計算法、調試程序帶來很大方便。

缺點:遞歸算法的運行效率較低,無論是耗費的計算時間還是占用的存儲空間都比非遞歸算法要多。

解決方法:在遞歸算法中消除遞歸調用,使其轉化為非遞歸算法。

采用一個用戶定義的棧來模擬系統的遞歸調用工作棧。該方法通用性強,但本質上還是遞歸,只不過人工做了本來由編譯器做的事情,優化效果不明顯。

用遞推來實現遞歸函數。

通過變換能將一些遞歸轉化為尾遞歸(尾遞歸是極其重要的,不用尾遞歸,函數的堆棧耗用難以估量,需要保存很多中間函數的堆棧。比如f(n, sum) = f(n-1) + value(n) + sum; 會保存n個函數調用堆棧,而使用尾遞歸f(n, sum) = f(n-1, sum+value(n)); 這樣則只保留后一個函數堆棧即可,之前的可優化刪去。)從而迭代求出結果:。

 

后兩種方法在時空復雜度上均有較大改善,但其適用范圍有限。

BFS的時間復雜度: O(n) , 因為每個點都只是進來出去一次, 一共n 個點


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM