105. Construct Binary Tree from Preorder and Inorder Traversal#42
Open
skypenguins wants to merge 1 commit into
Open
105. Construct Binary Tree from Preorder and Inorder Traversal#42skypenguins wants to merge 1 commit into
skypenguins wants to merge 1 commit into
Conversation
h-masder
reviewed
Jul 5, 2026
| ``` | ||
| - preorder は `root < left < right` の順序 | ||
| - inorder は `left < root < right` の順序 | ||
|
|
There was a problem hiding this comment.
言いたいことはわからなくもないですが、定義はしっかりと書いたほうが良いと思います。
特に、今回のアプローチはpreorderとinorderの性質を用いているので、なおさらです。
例えば、以下のサイトのように、定義と例を書いておいてもいいと思います。
https://www.geeksforgeeks.org/dsa/inorder-traversal-of-binary-tree/
https://www.geeksforgeeks.org/dsa/preorder-traversal-of-binary-tree/
h-masder
reviewed
Jul 5, 2026
|
|
||
| return root | ||
|
|
||
| return build_nodes(0, len(preorder) - 1, 0, len(inorder) - 1) |
There was a problem hiding this comment.
変数名は略さずに書いたほうが良いかなと思いました。また、midについては、rootのinorder indexという意味のほうが良いと思いました。
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
value_to_inoder_index = {val: i for i, val in enumerate(inorder)}
def build_nodes(preorder_left, preorder_right, inorder_left, inorder_right):
if preorder_left > preorder_right:
return None
root_value = preorder[preorder_left]
root = TreeNode(root_value)
root_inorder_index = value_to_inoder_index[root_value]
left_subtree_size = root_inorder_index - inorder_left
root.left = build_nodes(preorder_left + 1, preorder_left + left_subtree_size, inorder_left, root_inorder_index - 1)
root.right = build_nodes(preorder_left + left_subtree_size + 1, preorder_right, root_inorder_index + 1, inorder_right)
return root
return build_nodes(0, len(preorder) - 1, 0, len(inorder) - 1)There was a problem hiding this comment.
また、処理は若干複雑だと感じたので、適宜コメントを添えたりしてもいいのかなと思いました。試しに書いてみましたが、全体的に冗長かもしれません。
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_subtree(preorder_start, preorder_end, inorder_start, inorder_end):
if preorder_start > preorder_end:
return None
# preorder
# [root][left subtree][right subtree]
root_value = preorder[preorder_start]
root = TreeNode(root_value)
# inorder
# [left subtree][root][right subtree]
root_inorder_index = value_to_inorder_index[root_value]
left_subtree_size = root_inorder_index - inorder_start
# Update subtree ranges.
left_subtree_preorder_start = preorder_start + 1
left_subtree_preorder_end = preorder_start + left_subtree_size
right_subtree_preorder_start = left_subtree_preorder_end + 1
right_subtree_preorder_end = preorder_end
left_subtree_inorder_start = inorder_start
left_subtree_inorder_end = root_inorder_index - 1
right_subtree_inorder_start = root_inorder_index + 1
right_subtree_inorder_end = inorder_end
root.left = build_subtree(
left_subtree_preorder_start,
left_subtree_preorder_end,
left_subtree_inorder_start,
left_subtree_inorder_end,
)
root.right = build_subtree(
right_subtree_preorder_start,
right_subtree_preorder_end,
right_subtree_inorder_start,
right_subtree_inorder_end,
)
return root
return build_subtree(0, len(preorder) - 1, 0, len(inorder) - 1)
h-masder
reviewed
Jul 6, 2026
| stack.append(node.right) | ||
|
|
||
| return root | ||
| ``` |
There was a problem hiding this comment.
関数化したほうが分かりやすいかもしれません。
class Solution:
def buildTree(self, preorder, inorder):
if not preorder:
return None
root = TreeNode(preorder[0])
right_subtree_parent_candidates = [root]
inorder_index = 0
def find_right_subtree_parent(inorder_index):
while right_subtree_parent_candidates and right_subtree_parent_candidates[-1].val == inorder[inorder_index]:
parent_node = right_subtree_parent_candidates.pop()
inorder_index += 1
return parent_node, inorder_index
def attach_left_child(parent_node, child_node):
parent_node.left = child_node
right_subtree_parent_candidates.append(child_node)
def attach_right_child(parent_node, child_node):
parent_node.right = child_node
right_subtree_parent_candidates.append(child_node)
for node_value in preorder[1:]:
parent_node = right_subtree_parent_candidates[-1]
child_node = TreeNode(node_value)
if parent_node.val != inorder[inorder_index]:
attach_left_child(parent_node, child_node)
else:
parent_node, inorder_index = find_right_subtree_parent(inorder_index)
attach_right_child(parent_node, child_node)
return root
h-masder
reviewed
Jul 6, 2026
| return build_nodes(0, len(preorder) - 1, 0, len(inorder) - 1) | ||
| ``` | ||
|
|
||
| #### iterative DFS版 |
There was a problem hiding this comment.
再帰版とアプローチが異なるようですので、簡単に説明があると読みやすいかと思います。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
105. Construct Binary Tree from Preorder and Inorder Traversal
次回予告: 122. Best Time to Buy and Sell Stock II