問題描述
問題鏈接:https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
leetcode,medium
105:Construct Binary Tree from Preorder and Inorder Traversal
給定樹的前序遍歷和中序遍歷,請構建原來的二叉樹。假設不存在重複的元素。
Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
問題分析
舉個栗子:
preorder = [3,9,20,15,7]
inorder = [9,3,15,20,7]
首先要搞清楚二叉樹的前序遍歷和中序遍歷的特點,可以參考二叉樹的前序、中序、後序、層序遍歷方式,然後具體思路如下:
- 前序遍歷的數組的第1個元素一定是根節點元素,由此確定根節點元素;
- 由於所有元素都不重複,可以找出根節點元素在中序遍歷數組中的位置
index
,那麼中序遍歷數組中,index
之前的元素(一共有index
個,注意數組下標從0開始的)一定都是左子樹的節點,且是左子樹的中序遍歷結果,index
之後的元素一定都是右子樹的節點,且是右子樹的中序遍歷結果; - 前序遍歷數組中,從第二個元素開始往後一共
index
個元素是左子樹的前序遍歷結果,最後剩下的所有元素都是右子樹的前序遍歷結果; - 在步驟2、3中,得到左子樹的前序遍歷和中序遍歷,以及右子樹的前序遍歷和中序遍歷,那麼使用遞歸即可。
問題解法
結合上面思路,直接看代碼。
def construct_bt_preorder_inorder_traversal(preorder, inorder):
def build1(preorder, inorder):
if not preorder:
return None
if len(preorder) <= 1:
return TreeNode(preorder[0])
root_node = preorder[0]
root = TreeNode(root_node)
for i in range(len(inorder)):
if root_node == inorder[i]:
inorder_root_node_index = i
break
root.left = construct_bt_preorder_inorder_traversal(preorder[1:inorder_root_node_index+1], inorder[:inorder_root_node_index])
root.right = construct_bt_preorder_inorder_traversal(preorder[inorder_root_node_index+1:], inorder[inorder_root_node_index+1:])
return root
return build1(preorder, inorder)
測試代碼如下:
if __name__ == "__main__":
preorder = [3, 9, 20, 15, 7]
inorder = [9, 3, 15, 20, 7]
root = construct_bt_preorder_inorder_traversal(preorder, inorder)
print(layer_traverse(root))
輸出結果:[3, 9, 20, 15, 7]
哈哈,上面的layer_traverse實現的是二叉樹的層序遍歷,我是爲了打印方便,哈哈很容易實現,可以參考二叉樹的前序、中序、後序、層序遍歷方式中的層序遍歷或者找我要。