第四日

写代码的蓝胖子發表於2024-06-08

4. 從前序與中序遍歷序列構造二叉樹

題目描述:給定兩個整數陣列 preorder 和 inorder ,其中 preorder 是二叉樹的先序遍歷, inorder 是同一棵樹的中序遍歷,請構造二叉樹並返回其根節點。
示例

輸入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
輸出: [3,9,20,null,null,15,7]
初見想法

  1. 不懂如何構建樹
  2. 不知道前序和中序還原樹的規則
  3. 即使知道規則也不知道如何用於構建樹
    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)

思路理解

  1. 首先,建樹就是要定義一個有值,左右指標的物件
  2. 由於是遞迴地構建樹,所以要有終止條件,也就是當可供構建的序列其中一個為空時就停止構建,返回空
    而且,兩個序列一定同時為空或不為空,因為這兩個序列分別代表以該節點為根節點的樹的前中序遍歷。
  3. 所謂前中後序遍歷,實際上指的是根節點被遍歷的次序,描述的就是左右兩個孩子中間插入一個父節點,這時候有三個空位,插在哪個就是對應的遍歷。
    所以,透過前序遍歷的第一個元素,我們可以確定這兩個序列所對應的根節點,進而可以在中序遍歷中找到根節點的位置,這樣又可以分出左右兩棵子樹。
    這時的關鍵就在於如何確定兩棵子樹擁有的前中序遍歷,這就要涉及到一個關鍵的變數——根節點的位置,因為這涉及到左右子樹擁有的元素。
    如上圖所示,前序遍歷是根-左-右,中序遍歷是左-根-右,所以在中序遍歷中找到根節點的位置後,就可以根據其位置,獲取前序和中序遍歷的子樹陣列,因為遍歷是遞迴的,所以在原有樹下的遍歷順序在子樹下也一樣。
  4. 整個過程都在利用到建構樹的物件。
  5. 遞迴函式的返回就是根節點。