重建二叉樹

2021-10-10 22:34:11 字數 1679 閱讀 8435

輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。

例如,給出

前序遍歷 preorder = [3,9,20,15,7]

中序遍歷 inorder = [9,3,15,20,7]

返回如下的二叉樹:

3

/ \ 9

20/ \

157

限制:

0 <= 節點個數 <= 5000

思路:二叉樹的前序遍歷順序是:根節點、左子樹、右子樹,每個子樹的遍歷順序同樣滿足前序遍歷順序。

二叉樹的中序遍歷順序是:左子樹、根節點、右子樹,每個子樹的遍歷順序同樣滿足中序遍歷順序。

前序遍歷的第乙個節點是根節點,只要找到根節點在中序遍歷中的位置,在根節點之前被訪問的節點都位於左子樹,在根節點之後被訪問的節點都位於右子樹,由此可知左子樹和右子樹分別有多少個節點。

由於樹中的節點數量與遍歷方式無關,通過中序遍歷得知左子樹和右子樹的節點數量之後,可以根據節點數量得到前序遍歷中的左子樹和右子樹的分界,因此可以進一步得到左子樹和右子樹各自的前序遍歷和中序遍歷,可以通過遞迴的方式,重建左子樹和右子樹,然後重建整個二叉樹。

使用乙個 map 儲存中序遍歷的每個元素及其對應的下標,目的是為了快速獲得乙個元素在中序遍歷中的位置。呼叫遞迴方法,對於前序遍歷和中序遍歷,下標範圍都是從 0 到 n-1,其中 n 是二叉樹節點個數。

遞迴方法的基準情形有兩個:判斷前序遍歷的下標範圍的開始和結束,若開始大於結束,則當前的二叉樹中沒有節點,返回空值 null。若開始等於結束,則當前的二叉樹中恰好有乙個節點,根據節點值建立該節點作為根節點並返回。

若開始小於結束,則當前的二叉樹中有多個節點。在中序遍歷中得到根節點的位置,從而得到左子樹和右子樹各自的下標範圍和節點數量,知道節點數量後,在前序遍歷中即可得到左子樹和右子樹各自的下標範圍,然後遞迴重建左子樹和右子樹,並將左右子樹的根節點分別作為當前根節點的左右子節點。

/**

* definition for a binary tree node.

* public class treenode

* }*/class

solution

treenode tr =

buildtree

(preorder,

0,length-

1,inorder,

0,length-

1,indexmap)

;return tr;

}public treenode buildtree

(int

preorder,

int preorderstart,

int preorderend,

int[

] inorder,

int inorderstart,

int inorderend,map

indexmap)

int rootval = preorder[preorderstart]

; treenode root =

newtreenode

(rootval);if

(preorderstart == preorderend)

else

}}

時間複雜度:o(n)。

空間複雜度:o(n)。

二叉樹 重建二叉樹

問題 給定二叉樹的前序遍歷結果和中序遍歷結果,恢復出原二叉樹。假設二叉樹中的元素都不重複,給定二叉樹的前序遍歷序列,二叉樹的中序遍歷序列。看到此題,我首先想到的是尋找根節點,由前序遍歷序列可以看出根節點為1,此時通過中序遍歷可以看出來4,7,2在根節點的左子樹,5,3,8,6在樹的右節點。此時我們可...

二叉樹 重建二叉樹

題目給定兩個陣列,乙個是前序遍歷陣列 preorder 乙個是中序遍歷陣列 inorder 要求輸出還原二叉樹 核心在於我們要理解前序和中序便利的特點 前序遍歷 根節點 左節點 右節點 中序遍歷 左節點 根節點 右節點 所以我們從二叉樹的根節點開始重構 也就是preorder的第乙個值 同時用乙個m...

二叉樹重建

摘自劉汝佳的 演算法競賽入門經典 preorder t t 的根結點 preorder t 的左子樹 preorder t 的右子樹 inorder t inorder t 的左子樹 t 的根結點 inorder t 的右子樹 postorder t postorder t 的左子樹 postord...