From 61b3683ac655a91c88882e26d47fd935fe9bd94e Mon Sep 17 00:00:00 2001 From: Yota Maeda Date: Wed, 5 Aug 2026 00:26:17 +0900 Subject: [PATCH 1/2] step1,2 --- .../note.md | 22 +++++++++++ .../step1.py | 39 +++++++++++++++++++ .../step2.py | 39 +++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 105-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal/note.md create mode 100644 105-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal/step1.py create mode 100644 105-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal/step2.py diff --git a/105-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal/note.md b/105-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal/note.md new file mode 100644 index 0000000..9722247 --- /dev/null +++ b/105-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal/note.md @@ -0,0 +1,22 @@ +# 105. Construct Binary Tree from Preorder and Inorder Traversal + +https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/description/ + +## step1(まず通す) + +再帰で書くなら、 + +- preorder の先頭を取り出して、inorder の同じ数字を探す +- inorder の中で今見ているものより左にあるものは、左部分木、右にあるものは右の部分木 +- preorder は順番を保ったまま左右に振り分け + +単純にそのまま書いたが、配列のコピーや set にする処理が多く時間計算量で O(n^2) かかるので遅い。せめて添字で持つべき。 + +## step2(整形&他の人のコードを読む) + +- https://github.com/shintaro1993/arai60/pull/33/changes#diff-a286a96e11af3976f76d77e55be1edb9b540b1e2f1aabed1da12171208a553bcR24 + - 右の子を計算する時に node_index を node_index + split_index + 1 にすれば良い、というのに気づいていなかった + +## step3(10分以内にさっとかける \* 3回) + +stack でも書ける diff --git a/105-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal/step1.py b/105-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal/step1.py new file mode 100644 index 0000000..b5037cf --- /dev/null +++ b/105-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal/step1.py @@ -0,0 +1,39 @@ +from typing import Optional + + +class TreeNode: + def __init__(self, val=0, left=None, right=None): + self.val = val + self.left = left + self.right = right + + +class Solution: + def buildTree(self, preorder: list[int], inorder: list[int]) -> Optional[TreeNode]: + if not preorder: + return None + + if len(preorder) == 1: + return TreeNode(val=preorder[0]) + + value = preorder[0] + + inorder_index = inorder.index(value) + left_inorder = inorder[:inorder_index] + right_inorder = inorder[inorder_index + 1 :] + left_inorder_set = set(left_inorder) + right_inorder_set = set(right_inorder) + + left_preorder = [] + right_preorder = [] + for num in preorder: + if num in left_inorder_set: + left_preorder.append(num) + elif num in right_inorder_set: + right_preorder.append(num) + + return TreeNode( + val=value, + left=self.buildTree(preorder=left_preorder, inorder=left_inorder), + right=self.buildTree(preorder=right_preorder, inorder=right_inorder), + ) diff --git a/105-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal/step2.py b/105-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal/step2.py new file mode 100644 index 0000000..36c7eee --- /dev/null +++ b/105-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal/step2.py @@ -0,0 +1,39 @@ +from typing import Optional + + +class TreeNode: + def __init__(self, val=0, left=None, right=None): + self.val = val + self.left = left + self.right = right + + +class Solution: + def buildTree(self, preorder: list[int], inorder: list[int]) -> Optional[TreeNode]: + value_to_inorder_index = {value: index for index, value in enumerate(inorder)} + + def build_tree_with_indices( + inorder_begin: int, + inorder_end: int, + preorder_index: int, + ) -> Optional[TreeNode]: + if inorder_begin >= inorder_end: + return None + + value = preorder[preorder_index] + inorder_pivot = value_to_inorder_index[value] + return TreeNode( + val=value, + left=build_tree_with_indices( + inorder_begin, + inorder_pivot, + preorder_index + 1, + ), + right=build_tree_with_indices( + inorder_pivot + 1, + inorder_end, + preorder_index + (inorder_pivot - inorder_begin) + 1, + ), + ) + + return build_tree_with_indices(0, len(inorder), 0) From df99b596da7511f56ae2de1fb2c9c05324a09851 Mon Sep 17 00:00:00 2001 From: Yota Maeda Date: Wed, 5 Aug 2026 00:26:34 +0900 Subject: [PATCH 2/2] step3 --- .../step3.py | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 105-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal/step3.py diff --git a/105-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal/step3.py b/105-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal/step3.py new file mode 100644 index 0000000..0e93e9e --- /dev/null +++ b/105-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal/step3.py @@ -0,0 +1,43 @@ +from typing import Optional + + +class TreeNode: + def __init__(self, val=0, left=None, right=None): + self.val = val + self.left = left + self.right = right + + +class Solution: + def buildTree(self, preorder: list[int], inorder: list[int]) -> Optional[TreeNode]: + value_to_inorder_index = {value: index for index, value in enumerate(inorder)} + + root = TreeNode() + # stack: [(node, preorder_index, inorder_begin, inorder_end)] + stack = [(root, 0, 0, len(inorder))] + while stack: + node, preorder_index, inorder_begin, inorder_end = stack.pop() + node.val = preorder[preorder_index] + inorder_pivot = value_to_inorder_index[node.val] + if inorder_begin < inorder_pivot: + node.left = TreeNode() + stack.append( + ( + node.left, + preorder_index + 1, + inorder_begin, + inorder_pivot, + ) + ) + if inorder_pivot + 1 < inorder_end: + node.right = TreeNode() + stack.append( + ( + node.right, + preorder_index + (inorder_pivot - inorder_begin) + 1, + inorder_pivot + 1, + inorder_end, + ) + ) + + return root