LeetCode 105. 從前序與中序遍歷序列構造二叉樹 | Pyt
105. 從前序與中序遍歷序列構造二叉樹
題目來源:
題目
根據一棵樹的前序遍歷與中序遍歷構造二叉樹。
注意:
你可以假設樹中沒有重複的元素。
例如,給出
前序遍歷 preorder = [3,9,20,15,7]
中序遍歷 inorder = [9,3,15,20,7]
返回如下的二叉樹:
3
/
9 20
/
15 7
解題思路
思路:遞迴
在這裡,先講一下前序遍歷和中序遍歷的概念。
- 前序遍歷:首先訪問根節點,然後遍歷左子樹,最後遍歷右子樹。
- 中序遍歷:首先遍歷左子樹,然後訪問根節點,最後遍歷右子樹。
即是說兩者的遍歷順序分別為:
- 前序遍歷:根節點 -> 左子樹 -> 右子樹
- 中序遍歷:左子樹 -> 根節點 -> 右子樹
根據上面的順序可以看到,前序遍歷中,第一個就是根節點;而中序遍歷中,根節點的左側是左子樹,右側是右子樹。根據這個特性,先結合例子看下。
前序遍歷 preorder = [3,9,20,15,7]
中序遍歷 inorder = [9,3,15,20,7]
在這個例子當中,前序遍歷 preorder
的第一個元素 3
即是根節點,再看中序遍歷, inorder
中 3 的左邊 [9] 即是左子樹,而右邊 [15, 20, 7] 即是右子樹。根據這個思路,就能構造出完整的二叉樹。
這裡說下具體的思路:
- 首先找到根節點(依據:前序遍歷順序,先遍歷根節點)
- 構建根節點的左子樹(依據:中序遍歷,根節點的左側為左子樹)
- 構建根節點的右子樹(依據:中序遍歷,根節點的右側為右子樹)
題目中,有個提示:【假設樹中沒有重複的元素】。依據這個提示,我們在前序遍歷中找到的根節點元素,可根據元素值在中序遍歷中定位它的位置。
具體的程式碼實現如下。
程式碼實現
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
def build_tree(pre_left, pre_right, in_left, in_right):
"""構建二叉樹
Args:
pre_left: 前序遍歷左邊界
pre_right: 前序遍歷右邊界
in_left: 後序遍歷左邊界
in_right: 後序遍歷右邊界
"""
# 終止條件
if in_left > in_right:
return None
# 根據前序遍歷的順序,第一個元素就是根節點
pre_root = pre_left
# 構建根節點
root = TreeNode(preorder[pre_root])
# 因為題目提示,假設樹中沒有重複元素
# 那麼根據根節點的值,在 inorder 中定位
in_root = inorder.index(root.val)
# 根據中序遍歷的訪問順序,根節點的左邊即是左子樹,右邊是右子樹
# 在這裡先得到左子樹節點數目
size_left_subtree = in_root - in_left
# 構建左子樹
# 在這裡中序遍歷根節點左邊部分的節點(不包含根節點),其實就等同於前序遍歷左邊界下一位 + size_left_subtree 個節點
# 即是 in_left 到 inroot 前一位這部分節點,等同於 pre_left 的下一位開始的 size_left_subtree 個元素
root.left = build_tree(pre_left+1, pre_left+size_left_subtree, in_left, in_root-1)
# 構建右子樹
# 此時中序遍歷根節點右邊部分的節點(不包含根節點),對應前序遍歷左邊界 + 1 + sub_left_subtree 開始到其右邊界
root.right = build_tree(pre_left+1+size_left_subtree, pre_right, in_root + 1, in_right)
return root
size = len(inorder)
return build_tree(0, size-1, 0, size-1)
實現結果
總結
- 首先在根據前序遍歷訪問的順序,先找到二叉樹的根節點,構建根節點
- 因為題目說明可假設無重複元素,那麼可依據上面找到根節點的值,在中序遍歷 inorder 中找到其位置。
- 依據中序遍歷的訪問順序,可確定當前找到的根節點左側是左子樹,右側部分是右子樹
- 那麼根據上面分析的情況,遞迴構建左子樹,右子樹。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2318/viewspace-2825515/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- LeetCode 105. 從前序與中序遍歷序列構造二叉樹LeetCode二叉樹
- LeetCode-105-從前序與中序遍歷序列構造二叉樹LeetCode二叉樹
- LeetCode-106-從中序與後序遍歷序列構造二叉樹LeetCode二叉樹
- 從中序與後序遍歷序列構造二叉樹二叉樹
- 根據前序遍歷序列、中序遍歷序列,重建二叉樹二叉樹
- 從前序與中序構造二叉樹二叉樹
- Leetcode 889. 根據前序和後序遍歷構造二叉樹LeetCode二叉樹
- 106. 從中序與後序遍歷序列構造二叉樹——Java實現二叉樹Java
- 二叉樹:構造二叉樹(通過前序和中序遍歷)、映象翻轉、層次遍歷二叉樹
- 889. 根據前序和後序遍歷構造二叉樹二叉樹
- 【根據前序和中序遍歷構造二叉樹】棧+迭代 || 遞迴二叉樹遞迴
- 【LeetCode-二叉樹】二叉樹前序遍歷LeetCode二叉樹
- 二叉樹的前序、中序、後序三種遍歷二叉樹
- 根據二叉樹的前序遍歷和中序遍歷輸出二叉樹;二叉樹
- 144.二叉樹的前序遍歷145.二叉樹的後序遍歷 94.二叉樹的中序遍歷二叉樹
- 二叉樹的前序,中序,後序遍歷方法總結二叉樹
- 388,先序遍歷構造二叉樹二叉樹
- 【資料結構與演算法】二叉樹的 Morris 遍歷(前序、中序、後序)資料結構演算法二叉樹
- Leetcode——144. 二叉樹的前序遍歷LeetCode二叉樹
- 中序線索二叉樹的構造和遍歷二叉樹
- LeetCode題144. 二叉樹的前序遍歷LeetCode二叉樹
- 144. 二叉樹的遍歷「前序、中序、後序」 Golang實現二叉樹Golang
- Leetcode——94.二叉樹的中序遍歷LeetCode二叉樹
- 刷題系列 - 給出前序和後序遍歷佇列,構造對應二叉樹佇列二叉樹
- 程式碼隨想錄演算法訓練營day14 | leetcode 144. 二叉樹的前序遍歷、145. 二叉樹的後序遍歷、94. 二叉樹的中序遍歷演算法LeetCode二叉樹
- 二叉樹迭代器(中序遞迴、前序和後序遍歷)演算法二叉樹遞迴演算法
- 刷題筆記:樹的前序、中序、後序遍歷筆記
- 144. 二叉樹的前序遍歷(java實現)--LeetCode二叉樹JavaLeetCode
- 【樹01】對二叉樹前序/中序/後序遍歷演算法的一些思考二叉樹演算法
- 二叉搜尋樹的後序遍歷序列
- L2_006樹的遍歷(後序+中序->前序/層序)
- 144. 二叉樹的前序遍歷二叉樹
- 刷題系列 - 中序和後序遍歷佇列,構造對應二叉樹;佇列二叉樹
- LeetCode102.二叉樹的層序遍歷LeetCode二叉樹
- 劍指offer:輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。二叉樹
- 中序線索二叉樹的建立與遍歷二叉樹
- 先序、中序、後序序列的二叉樹構造演算法二叉樹演算法
- LeetCode-107-二叉樹的層序遍歷 IILeetCode二叉樹