1. 程式人生 > 實用技巧 >劍指offer04-重建二叉樹

劍指offer04-重建二叉樹

題目描述

輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。 示例1

輸入: [1,2,3,4,5,6,7],[3,2,4,1,6,5,7]

返回值:{1,2,5,3,4,6,7}

知識點

通過前序+中序還原樹結構:

在二叉樹的前序遍歷序列中,第一個數字總是樹的根結點的值。但在中序遍歷序列中,根結點的值在序列的中間,左子樹的結點的值位於根結點的值的左邊,而右子樹的結點的值位於根結點的值的右邊。因此我們需要掃描中序遍歷序列,才能找到根結點的值。

前序遍歷序列的第一個數字1就是根結點的值。掃描中序遍歷序列,就能確定根結點的值的位置。根據中序遍歷特點,在根結點的值1前面的3個數字都是左子樹結點的值,位於1後面的數字都是右子樹結點的值。

在二叉樹的前序遍歷和中序遍歷的序列中確定根結點的值、左子樹結點的值和右子樹結點的值的步驟如下圖所示:

分別找到了左、右子樹的前序遍歷序列和中序遍歷序列,我們就可以用同樣的方法分別去構建左右子樹。換句話說,這是一個遞迴的過程。

思路總結:先根據前序遍歷序列的第一個數字建立根結點,接下來在中序遍歷序列中找到根結點的位置,這樣就能確定左、右子樹結點的數量。在前序遍歷和中序遍歷的序列中劃分了左、右子樹結點的值之後,就可以遞迴地去分別構建它的左右子樹。

程式碼

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回構造的TreeNode根節點
    def reConstructBinaryTree(self, pre, tin):
        # write code here
        if not len(pre):
            
return None pRoot=TreeNode(pre[0]) --構造根節點 flg=tin.index(pre[0]) pRoot.left=self.reConstructBinaryTree(pre[1:flg+1],tin[0:flg]) --構造左子樹 pRoot.right=self.reConstructBinaryTree(pre[flg+1:],tin[flg+1:]) --構造右子樹 return pRoot