# **Leetcode筆記(Construct Binary Tree from Preorder and Inorder Traversal)** :::info :information_source: 題目 : Construct Binary Tree from Preorder and Inorder Traversal, 類型 : binary tree , 等級 : medium 日期 : 2023/03/18,2023/05/24,2023/07/07,2024/10/18 ::: ### 嘗試 時間複雜度O(n),空間複雜度O(n) ```python class Solution: def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: # 前序 (preorder): 中 -> 左 -> 右 # 中序 (inorder): 左 -> 中 -> 右 res = list() leftl = list() rightl = list() res.append(root) for i < len(inorder): if inorder[i] == preorder[0]: node = preorder leftl = inorder[0, i] rightl = inorder[i, 0] ``` 2023/05/24 ```python class Solution: def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: # 前序 (preorder): 中 -> 左 -> 右 # 中序 (inorder): 左 -> 中 -> 右 if not preorder and not inorder: return None root = TreeNode(preorder[0]) # 在inorder的mid mid = inorder.index(preorder[0]) # 不包含root -> preorder[1 : mid + 1] root.left = self.buildTree(preorder[1 : mid + 1], inorder[ : mid]) root.right = self.buildTree(preorder[mid + 1: ], inorder[mid + 1 : ]) return root ``` 2023/07/07 可以畫[這裡](https://www.youtube.com/watch?v=wDsFfgv4OGY)這種123方法去思考遞迴 每個node都會有當到root的機會,會先處理最左邊的那個node,並把結果回傳給上一層的root.left 步驟 : 一開始先抓住preorder[0],在去inorder抓index,分辨left和right ```python class Solution: def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: if not preorder or not inorder: return None root = TreeNode(preorder[0]) index = inorder.index(preorder[0]) # 分界index root.left = self.buildTree(preorder[1 : index + 1], inorder[0 : index]) root.right = self.buildTree(preorder[index + 1 : ], inorder[index + 1 : ]) return root ``` 如果有preorder[:0]的話,會是取到空字串,不會有錯誤,照樣可以被視為list傳 要記得,如果是取pre/in,需要撇開root,然後pre/in的list長度會相同 可以用list.index去取index ```python class Solution: def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: if not preorder or not inorder: return None root = TreeNode(preorder[0]) i = inorder.index(preorder[0]) root.left = self.buildTree(preorder[1:i + 1], inorder[:i]) root.right = self.buildTree(preorder[i + 1:], inorder[i + 1:]) return root ``` 2024/10/18 給定inorder和preorder的array,重新建成tree inorder分法很直觀,preorder只要記得,分配到數字的數量會是一樣的就好 ```python class Solution: def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: return self.reconstruct(preorder, inorder) def reconstruct(self, preorder, inorder): if not preorder or not inorder: return None root = preorder[0] i = inorder.index(root) left = self.reconstruct(preorder[1:i + 1], inorder[:i]) right = self.reconstruct(preorder[i + 1:], inorder[i + 1:]) return TreeNode(root, left, right) ``` --- ### **優化** 已知Preorder 的第一個 element 會是根,而 Preorder 的問題會是,在後面的 element,不知道有哪些是屬於左子樹,哪些是右子樹,也許全都是左子樹,也可能全部都是右子樹。 這邊可以藉由 Inorder 來判斷。 假設 Preorder 的第一個 element 是 r0,則在 Inorder中,r0 之前的,就是左子樹;r0 之後的,就是右子樹,跟據左子樹跟右子樹的這些 elements,就可以判斷在 Preorder 當中,哪些屬於左子樹,哪些是右子樹。 時間複雜度O(n) ```python class Solution: def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: # 前序 (preorder): 中 -> 左 -> 右 # 中序 (inorder): 左 -> 中 -> 右 if not preorder or not inorder: return None root = TreeNode() root.val = preorder[0] mid = inorder.index(root.val) root.left = self.buildTree(preorder[1 : mid + 1], inorder[: mid]) root.right = self.buildTree(preorder[mid + 1 : ], inorder[mid + 1:]) return root ``` --- **:warning: 錯誤語法** :::warning 初始化樹點 : TreeNode() ::: **:thumbsup:學習** :::success 前序 (preorder): 中 -> 左 -> 右 中序 (inorder): 左 -> 中 -> 右 後序 (postorder): 左 -> 右 -> 中 List.index( 某東西 ) -> 會回傳其在list中對應的index ::: **思路** **講解連結** Provided by. NeetCode https://medium.com/@cashbooktw/construct-binary-tree-with-preorder-and-inorder-traversal-c50fb945f00f ###### tags: `binary tree` `medium` `leetcode`