7. 遞歸:如何用三行代碼找到“最終推薦人”

一、什麼是遞歸?
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.警惕重複計算:通過某種數據結構來保存已經求解過的值,從而避免重複計算。

六、如何將遞歸改寫爲非遞歸代碼?
籠統的講,所有的遞歸代碼都可以改寫爲迭代循環的非遞歸寫法。如何做?抽象出遞推公式、初始值和邊界條件,然後用迭代循環實現。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章