4. 從前序與中序遍歷序列構造二叉樹
題目描述:給定兩個整數陣列 preorder 和 inorder ,其中 preorder 是二叉樹的先序遍歷, inorder 是同一棵樹的中序遍歷,請構造二叉樹並返回其根節點。
示例:
輸入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
輸出: [3,9,20,null,null,15,7]
初見想法
- 不懂如何構建樹
- 不知道前序和中序還原樹的規則
- 即使知道規則也不知道如何用於構建樹
GPT程式碼
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def buildTree(preorder, inorder):
if not preorder or not inorder:
return None
root_val = preorder[0]
root = TreeNode(root_val)
root_index = inorder.index(root_val)
root.left = buildTree(preorder[1:root_index+1], inorder[:root_index])
root.right = buildTree(preorder[root_index+1:], inorder[root_index+1:])
return root
# 示例輸入
preorder = [3, 9, 20, 15, 7]
inorder = [9, 3, 15, 20, 7]
# 構建二叉樹
root = buildTree(preorder, inorder)
# 遍歷二叉樹
def postorder_traversal(node):
if node:
postorder_traversal(node.left)
postorder_traversal(node.right)
print(node.val)
postorder_traversal(root)
思路理解
- 首先,建樹就是要定義一個有值,左右指標的物件
- 由於是遞迴地構建樹,所以要有終止條件,也就是當可供構建的序列其中一個為空時就停止構建,返回空
而且,兩個序列一定同時為空或不為空,因為這兩個序列分別代表以該節點為根節點的樹的前中序遍歷。
- 所謂前中後序遍歷,實際上指的是根節點被遍歷的次序,描述的就是左右兩個孩子中間插入一個父節點,這時候有三個空位,插在哪個就是對應的遍歷。
所以,透過前序遍歷的第一個元素,我們可以確定這兩個序列所對應的根節點,進而可以在中序遍歷中找到根節點的位置,這樣又可以分出左右兩棵子樹。
這時的關鍵就在於如何確定兩棵子樹擁有的前中序遍歷,這就要涉及到一個關鍵的變數——根節點的位置,因為這涉及到左右子樹擁有的元素。
如上圖所示,前序遍歷是根-左-右,中序遍歷是左-根-右,所以在中序遍歷中找到根節點的位置後,就可以根據其位置,獲取前序和中序遍歷的子樹陣列,因為遍歷是遞迴的,所以在原有樹下的遍歷順序在子樹下也一樣。 - 整個過程都在利用到建構樹的物件。
- 遞迴函式的返回就是根節點。