遞迴轉非遞迴

2021-09-01 15:58:17 字數 2584 閱讀 8292

題目描述

給定乙個列表,該列表中的每個要素要麼是個列表,要麼是整數。將其變成乙個只包含整數的簡單列表。

如果給定的列表中的要素本身也是乙個列表,那麼它也可以包含列表。

您在真實的面試中是否遇到過這個題?

樣例給定 [1,2,[1,2]],返回 [1,2,1,2]。

給定 [4,[3,[2,[1]]]],返回 [4,3,2,1]。

挑戰請用非遞迴方法嘗試解答這道題。

處理所有資料,都在出棧時進行處理

根節點首先入棧再開啟迴圈

使用輔助資料結構管理出棧

由於本題很特殊,本題的list節點可以認為對本節點的操作為空, 所以本題用三種方法解都可以

public

static

void

preorderunrecur

(node head)

if(head.left != null)}}

system.out.

println()

;}

可以看到, 先序的處理最簡單

從棧中彈出乙個, 處理

將右子樹入棧

將左子樹入棧

迴圈到棧空

先壓右子樹, 就可以保證棧頂的是左子樹.

用這種思路來處理本題可以寫出如下ac**

public

class

solution

return re;

}void

flatternmyself

(nestedinteger integer,list

container)

else

if(tempint.

isinteger()

)else}}

}}}

public

static

void

inorderunrecur

(node head)

else}}

system.out.

println()

;}

中序遍歷的思路主要是, 先一路壓左, 對應遞迴寫法一上來直接遞迴左子樹. 壓到空, 對應葉子節點, 然後出棧處理本節點, 再壓右.

如果不使用上述寫法, 使用兩層while寫法, 一定要把空指標入棧, 不迴圈壓左子樹的時候, 無法知道當前節點是第一次遇到, 還是左子樹已經壓過, 從左子樹回來之後遇到的.

如下 :

class

solution

stack> nes;

nes.

push

(root)

;while

(!nes.

empty()

) nes.

pop();

// 如果頭節點沒有右子樹, 可能出現棧中只有乙個null的情況, 上面pop以後, 這裡可能就會empty, 所以要判斷一下

// 但是這裡不用判斷棧頂, 因為不可能出現連續有兩個null的情況

// 因為遇到乙個空以後, 就不會push, 然後就將空pop了if(

!nes.

empty()

)}return ans;}}

;

這種寫法的處理對應本題需要在class中增加乙個mark以便在壓入右子樹的時候,找到當前list的下乙個應該被壓的節點. oj太傻, 所以本題這種寫法暫時不做, 意會就行

public

static

void

posorderunrecur1

(node head)

if(head.right != null)

}while

(!s2.

isempty()

)}system.out.

println()

;}

後序第一種寫法, 用乙個輔助棧, 將先序的順序調整為後序, 關鍵還是在出棧時處理資料

可寫出如下ac**

public

class

solution

return re;

}void

flatternmyself

(nestedinteger integer,list

container)

else

if(tempint.

isinteger()

)else}}

}while

(!helpstack.

empty()

)}}

public

static

void

posorderunrecur2

(node h)

else

if(c.right != null && h != c.right)

else}}

system.out.

println()

;}

後序第二種

消除遞迴的方法 遞迴轉非遞迴

利用棧來人工模擬系統堆疊的操作過程,其實這種方法本質上還是遞迴,只不過本來計算機幫你完成的事由你自己做了,所以這對演算法的優化效果不明顯。如果遞迴函式是尾遞迴 在函式末尾遞迴呼叫本函式的方式,且遞迴呼叫語句只有乙個 就可以很容易的將遞迴消除,用推導出來的數學公式代替。其效率與迴圈的 執行效率基本上是...

遞迴 非遞迴

遞迴演算法實際上是一種分而治之的方法,它把複雜問題分解為簡單問題來求解。對於某些複雜問題 例如 hanio塔問題 遞迴演算法是一種自然且合乎邏輯的解決問題的方式,但是遞迴演算法的執行效率通常比較差。因此 在求解某些問題時,常採用遞迴演算法來分析問題,用非遞迴演算法來求解問題 另外,有些程式語言不支援...

資料結構 演算法 14 遞迴 轉非遞迴

目錄遞迴 改為非遞迴 遞迴是一種應用非常廣泛的演算法 程式設計技巧,如 所有的遞迴都可以轉為非遞迴實現。李柱明部落格 遞迴的定義 遞迴與棧結構 優點 遞迴 的表達力很強,寫起來非常簡潔。缺點 空間複雜度高。有堆疊溢位的風險。存在重複計算。過多的函式呼叫會耗時較多。遞迴需要滿足的兩個條件 乙個問題可以...