資料結構與演算法之美 8 遞迴演算法

2021-10-21 23:50:09 字數 1229 閱讀 5299

遞迴嚴格說起來不算一種演算法,只能說是一種問題處理思想或者問題處理技巧。只要問題同時滿足以下三個條件,就可以考慮用遞迴來解決:

乙個問題的解可以分解為幾個子問題的解

這個問題與分解之後的子問題,除了資料規模不同,求解思路完全一樣

存在遞迴終止條件

個人覺得,寫遞迴**最關鍵的是寫出遞推公式,找到終止條件。

下面舉乙個例子,然後一步一步實現乙個遞迴**,幫你理解遞迴思想:

假如這裡有 n 個台階,每次你可以跨 1 個台階或者 2 個台階,請問走這 n 個台階有多少種走法?

解析:我們先假設n個台階有x個走法,即x = f(n)。對於第一步,我們有兩種走法,(1)走1個台階,剩餘n-1個台階。(2)走2個台階,剩餘n-2個台階。所以由此我們可以推導出f(n)=f(n-1) + f(n-2),遞迴格式我們已經推導出來了,下面我們再來分析一下終止條件:隨著我們不同走法,最後台階要麼剩下1個,要麼剩下2個,如果是1個,很簡單,下一步只能走1個台階,即f(1)=1。如果剩餘2個台階,下一步我們有兩個選擇,即一次走兩個台階和兩次每次走1個台階,即f(2) = 2。

綜上,遞迴格式為f(n) = f(n-1) + f(n-2)。

終止條件為:f(1) = 1或者f(2) = 2

int f(int n)  else 

}

寫遞迴**的關鍵就是找到如何將大問題分解為小問題的規律,並且基於此寫出遞推公式,然後再推敲終止條件,最後將遞推公式和終止條件翻譯成**。不用想一層層的呼叫關係,不要試圖用人腦去分解遞迴的每個步驟。

在寫遞迴**時候,需要注意以下兩點:

警惕堆疊溢位,如果遞迴求解的資料規模很大,呼叫層次很深,一直壓入棧,就會有堆疊溢位的風險。可以通過在**中限制遞迴呼叫的最大深度的方式來解決這個問題。要警惕重複計算,可以通過乙個資料結構(比如雜湊表)來儲存已經求解過的 f(k)。函式呼叫耗時多、空間複雜度高

遞迴是一種非常高效、簡潔的編碼技巧。只要是滿足「三個條件」的問題就可以通過遞迴**來解決。編寫遞迴**的關鍵就是正確姿勢是寫出遞推公式,找出終止條件,然後再翻譯成遞迴**。遞迴**雖然簡潔高效,但是,遞迴**也有很多弊端。比如,堆疊溢位、重複計算、函式呼叫耗時多、空間複雜度高等,所以,在編寫遞迴**的時候,一定要控制好這些***。

《資料結構與演算法之美》07 遞迴

一 如何理解 遞迴 遞迴是一種應用非常廣泛的演算法 或者程式設計技巧 二 遞迴的三個條件 1 乙個問題的解可以分解為幾個子問題的解 2 這個問題與分解之後的子問題,除了資料規模不同,求解思路完全一樣 3 存在遞迴終止條件 三 如何編寫遞迴 寫遞迴 最關鍵的是 找到如何將大問題分解為小問題的規律,並且...

資料結構與演算法之美

什麼是資料結構?什麼是演算法 狹義重點 複雜度分析 方法 邊學邊練,適度刷題 複雜度分析 時間複雜度 常見時間複雜度 非多項式量級 非常低效的演算法 空間複雜度 漸進空間複雜度,表示演算法的儲存空間和資料規模的增長關係 最好情況時間複雜度 理想情況的時間複雜度 最壞情況時間複雜度 最糟糕的情況下的時...

資料結構與演算法之遞迴

以階乘舉例 def factorial n 階乘 if n 0 return 1 else return n factorial n 1 函式每被呼叫一次就會被壓棧,而且引數減一再次呼叫再次壓棧,當達到終止條件時,遞迴就會終止,從棧底往上返回return的結果。二分查詢 終止條件 找到終止 目標值等...