本人的遞歸水平一直很爛 有一段時間不寫代碼 再寫的時候 就會不自覺的避開遞歸的想法 並且日常作的題目 好比樹或者圖的DFS,或者backtracking DP等等 只要能避開遞歸就避開 久而久之,每次遇到一個新的題目,本身的思惟裏面跟本就沒有遞歸思想,或者就算知道這種應該遞歸作可是內心仍然在打怵,因此接下來就說一下最適合個人遞歸思路。數據結構
首先就不要怕 怕個錘子 不就是寫錯了嘛 又不是說遞歸必定是對的啥的。ide
首先啥是遞歸?
遞歸的能力在於用有限的語句來定義對象的無限集合。通常來講,遞歸須要有邊界條件、遞歸前進段和遞歸返回段。當邊界條件不知足時,遞歸前進;當邊界條件知足時,遞歸返回。函數
而後就是想想參數列表,這些參數 有些是咱們真正的輸入,好比整個圖的hashmap,有些參數 是咱們在遞歸的過程當中逐步構建,他們是最後的答案或者是答案的一部分,有些參數 是咱們的指針 用於遍歷輸入的map的指針。(有的時候 咱們在作圖的題目的時候 會在參數列表中加上curNode這一項 而後還會加入seen/visited這一項)指針
而後想想這個函數是幹嗎的 雖然都叫dfs可是他只是一個空殼。這個時候找到等價關係式,就跟DP裏面的公式同樣。(先不要考慮corner case和遞歸終止條件)對象
而後再想想這個遞歸終止的條件是什麼。咱們到底是要 返回void 仍是每次要尾遞歸 仍是不要尾遞歸。整體來講狀況有如下幾種:咱們不返回void,可是咱們使用尾遞歸 或者 咱們不返回void,可是咱們使用提早遞歸 或者 咱們返回void 這樣的話基本上是要提早終止或者最後終止(即return的位置)
注意 return和是否是用尾遞歸沒啥關係 尾遞歸只是後return了一個當前遞歸函數而已,若是咱們這個遞歸函數返回void的話 就直接寫遞歸函數就好了 根本不用return。遞歸
最後 有哪些東西用遞歸用的多呢?
鏈表原本是一個很好的用遞歸的數據結構 可是實際我寫代碼的時候不多用。
樹:這個數據結構簡直就是爲遞歸量身打造的,除了BFS咱們推薦用Queue以外 其餘的須要咱們前序中序後序遍歷的時候要用遞歸(就是說 找路徑的時候)
圖:DFS的時候咱們最好也用遞歸
此外 還有 在構建 並查集的時候find()函數最好也用遞歸。hash