題目:
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。
關於樹的概念:
樹是一種在實際程式設計中經常遇到的資料結構。它的邏輯很簡單:除根節點之外每個節點只有一個父節點,根節點沒有父節點;除葉節點之外所有的節點都有一個或多個子節點,葉節點沒有子節點。父節點和子節點之間用指標連結。
面試的時候提到的樹,大部分是二叉樹。所謂二叉樹是樹的一種特殊結構,在二叉樹中每個節點最多隻有兩個子節點。
在二叉樹中最重要的操作莫過於遍歷,即按照某一順序訪問樹中的所有子節點。
通常樹有如下幾種遍歷方式:
- 前序遍歷:先訪問根結點,再訪問左子結點,最後訪問右子結點。
- 中序遍歷:先訪問左子結點,再訪問根結點,最後訪問右子結點。
- 後序遍歷:先訪問左子結點,再訪問右子結點,最後訪問根結點。
- 寬度優先遍歷:先訪問樹的第一層節點,再訪問樹的第二層節點…一直到訪問到最下面一層節點。
二叉樹有很多特例,二叉搜尋樹就是其中之一。在二叉搜尋樹中,左子節點總是小於或等於根節點,而右子節點總是大於或等於根子節點。
二叉樹的另外兩個特例是堆和紅黑樹。堆分為最大堆和最小堆。在最大堆中根節點的值最大,在最小堆中根節點的值最小。有很多需要快速找到最大值或者最小值的問題都可以用堆來解決。紅黑樹是把樹中的節點定義為紅、黑兩種顏色,並通過規則確保從根節點到葉節點的最長路徑的長度不超過最短路徑的兩倍。
思路:
前序遍歷序列中,第一個數字總是樹的根結點的值。在中序遍歷序列中,根結點的值在序列的中間,左子樹的結點的值位於根結點的值的左邊,而右子樹的結點的值位於根結點的值的右邊。剩下的我們可以遞迴來實現。
程式實現:
# -*- 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 len(pre)==0: return None elif len(pre)==1: return TreeNode(pre[0]) else: root = TreeNode(pre[0]) pos = tin.index(pre[0]) root.left = self.reConstructBinaryTree(pre[1:pos+1],tin[:pos]) root.right = self.reConstructBinaryTree(pre[pos+1:],tin[pos+1:]) return root