Leetcode 106:從中序與後序遍歷序列構造二叉樹(最詳細的解法!!!)
阿新 • • 發佈:2018-12-17
根據一棵樹的中序遍歷與後序遍歷構造二叉樹。
注意: 你可以假設樹中沒有重複的元素。
例如,給出
中序遍歷 inorder = [9,3,15,20,7]
後序遍歷 postorder = [9,15,7,20,3]
返回如下的二叉樹:
3
/ \
9 20
/ \
15 7
解題思路
class Solution:
def buildTree(self, inorder, postorder):
"""
:type inorder: List[int]
:type postorder: List[int]
:rtype: TreeNode
"""
if inorder:
ind = inorder.index(postorder.pop())
root = TreeNode(inorder[ind])
root.right = self.buildTree(inorder[ind+1:], postorder)
root.left = self.buildTree(inorder[:ind], postorder)
return root
注意上面寫法與之前寫法的區別,也就是root.right
root.left
的前後位置問題。
同樣的可以寫出迭代版本。對於迭代的關鍵還是在於找根節點。我我們通過postorder
知道3
是整棵樹的根節點,所以我們建立一個stack
,然後將3
加入到stack
中。棧頂是我們每次要考慮的根節點,我們每次從後向前遍歷postorder
中的元素。我們首先考慮20
應該放在哪?通過postorder
我們知道20
一定是root右子樹
的根節點,所以我們將9
加入到root(3).right
。
stack: 3 20
3
\
20
我們接著考慮7
應該放在哪。我們通過postorder
知道7
一定是20
右子樹的根節點,所以我們將7
放在20
的右邊。
stack: 3 20 7 3 \ 20 \ 7
接著尋找7
的左右孩子,我們通過inorder
推斷出7
沒有左右孩子。所以我們將7
出棧。
stack: 3 20
3
\
20
\
7
我們接著考慮15
應該放在哪。我們通過postorder
知道15
一定是20
左孩子的根節點。我們將15
入棧。
stack: 3 20 15
3
\
20
/ \
15 7
通過inorder
我們知道15
沒有左右孩子,所以我們將15
出棧。我們發現20
的左右子樹已經填滿了,所以我們將20
也出棧。
stack: 3
3
\
20
/ \
15 7
我們接著考慮9
應該放在哪。我們發現3
的左邊還是空的,所以我們將9
放到3
的左邊。同時將9
入棧
stack: 3 9
3
/ \
9 20
/ \
15 7
接著就是具體實現上的細節。
class Solution:
def buildTree(self, inorder, postorder):
"""
:type inorder: List[int]
:type postorder: List[int]
:rtype: TreeNode
"""
if not inorder or not postorder:
return
postorder.reverse()
root = TreeNode(postorder[0])
stack = [root]
i = len(inorder) - 1
for node in postorder[1:]:
parent = stack[-1]
if parent.val != inorder[i]:
parent.right = TreeNode(node)
stack.append(parent.right)
else:
while stack and stack[-1].val == inorder[i]:
parent = stack.pop()
i -= 1
parent.left = TreeNode(node)
stack.append(parent.left)
return root
如有問題,希望大家指出!!!