題目描述:給定一棵二元樹的中序走訪陣列 inorder 和後序走訪陣列 postorder(保證樹中無重複值),請重建並返回該二元樹的根節點。
解題思路:
利用後序走訪的關鍵特性:後序陣列的最後一個元素永遠是當前子樹的根節點。知道根節點後,再利用中序走訪的特性——根節點將中序陣列切分為左子樹和右子樹——即可遞迴地重建整棵樹。
postorder[postEnd] 即為當前子樹的根。unordered_map<int, int>),以 O(1) 找到根在中序陣列中的索引 inMid。leftSize = inMid - inStart。[inStart, inMid - 1];後序範圍:[postStart, postStart + leftSize - 1]。[inMid + 1, inEnd];後序範圍:[postStart + leftSize, postEnd - 1]。使用雜湊表將中序查詢從 O(n) 降至 O(1),整體時間複雜度為 O(n)。
時間複雜度:O(n) — 建立雜湊表需 O(n);之後每個節點只被遞迴函式處理一次(每次呼叫建立一個節點),共 n 次呼叫,每次查詢雜湊表為 O(1),整體 O(n)。
空間複雜度:O(n) — 雜湊表儲存 n 個元素需 O(n);遞迴呼叫堆疊深度在最壞情況(退化為單鏈)為 O(n),平衡樹則為 O(log n)。
1. Build a hash map: inorderIndex[value] = index for all elements in inorder. 2. Call build(inorder, postorder, inStart=0, inEnd=n-1, postStart=0, postEnd=n-1). 3. In build(inStart, inEnd, postStart, postEnd): a. If inStart > inEnd, return null. b. rootVal = postorder[postEnd]. c. Create a new TreeNode with rootVal. d. inMid = inorderIndex[rootVal]. e. leftSize = inMid - inStart. f. root.left = build(inStart, inMid-1, postStart, postStart+leftSize-1). g. root.right = build(inMid+1, inEnd, postStart+leftSize, postEnd-1). h. Return root.
方法一:線性掃描(不用雜湊表)
每次在中序陣列中用線性掃描找根節點位置,不需要額外空間建立雜湊表。時間複雜度退化為 O(n²)(每層遞迴掃描一次),空間複雜度 O(n)(遞迴堆疊)。適合題目保證 n 很小的情形,但一般情況下效率不佳。
方法二:迭代 + 明確堆疊模擬
使用明確的堆疊(stack<TreeNode*>)和反向走訪後序陣列(從尾端往前相當於前序的鏡像),搭配中序陣列指標進行迭代重建。時間複雜度 O(n),空間複雜度 O(n)。此方法避免了系統遞迴堆疊溢位的風險,適合 n 極大的情形,但實作較複雜。