1.遞迴是一種非常高效、簡潔的編碼技巧,一種應用非常廣泛的演算法,比如dfs深度優先搜尋、前中後序二叉樹遍歷等都是使用遞迴。
2.方法或函式呼叫自身的方式稱為遞迴呼叫,呼叫稱為遞,返回稱為歸。
3.基本上,所有的遞迴問題都可以用遞推公式來表示,比如
f(n) = f(n-1) + 1;
f(n) = f(n-1) + f(n-2);
f(n)=n*f(n-1);
1.優點:**的表達力很強,寫起來簡潔。
2.缺點:空間複雜度高、有堆疊溢位風險、存在重複計算、過多的函式呼叫會耗時較多等問題。
乙個問題只要同時滿足以下3個條件,就可以用遞迴來解決:
1.問題的解可以分解為幾個子問題的解。何為子問題?就是資料規模更小的問題。
2.問題與子問題,除了資料規模不同,求解思路完全一樣
3.存在遞迴終止條件
1.遞迴**編寫
寫遞迴**的關鍵就是找到如何將大問題分解為小問題的規律,並且基於此寫出遞推公式,然後再推敲終止條件,最後將遞推公式和終止條件翻譯成**。
2.遞迴**理解
對於遞迴**,若試圖想清楚整個遞和歸的過程,實際上是進入了乙個思維誤區。
那該如何理解遞迴**呢?如果乙個問題a可以分解為若干個子問題b、c、d,你可以假設子問題b、c、d已經解決。而且,你只需要思考問題a與子問題b、c、d兩層之間的關係即可,不需要一層層往下思考子問題與子子問題,子子問題與子子子問題之間的關係。遮蔽掉遞迴細節,這樣子理解起來就簡單多了。
因此,理解遞迴**,就把它抽象成乙個遞推公式,不用想一層層的呼叫關係,不要試圖用人腦去分解遞迴的每個步驟。
1.警惕堆疊溢位:可以宣告乙個全域性變數來控制遞迴的深度,從而避免堆疊溢位。
2.警惕重複計算:通過某種資料結構來儲存已經求解過的值,從而避免重複計算。
籠統的講,所有的遞迴**都可以改寫為迭代迴圈的非遞迴寫法。如何做?抽象出遞推公式、初始值和邊界條件,然後用迭代迴圈實現。
一步步學ROS
最近因為看svo的 裡面用到catkin決定要好好看ros,年前學會基本操作。啟動節點 rosrun package name executable name 檢視節點 rosnode list 注 rosout 節點是乙個特殊的節點,通過 roscore 自動啟動 檢視特定節點的資訊 rosnod...
一步步學資料結構與演算法 20 雜湊演算法 上
帶著問題來學習 1.如何防止資料庫中的使用者資訊被脫庫?2.你會如何儲存使用者密碼這麼重要的資料嗎?僅僅 md5 加密一下儲存就夠了嗎?3.在實際開發中,我們應該如何用雜湊演算法解決問題?1.定義 將任意長度的二進位制值串對映成固定長度的二進位制值串,這個對映的規則就是雜湊演算法,而通過原始資料對映...
一步步學資料結構與演算法 09 佇列
1.先進者先出,這就是典型的 佇列 結構。2.支援兩個操作 入隊enqueue 放乙個資料到隊尾 出隊dequeue 從隊頭取乙個元素。3.所以,和棧一樣,佇列也是一種操作受限的線性表。1.佇列api public inte ce queue2.陣列實現 順序佇列 public class arra...