diff --git "a/\347\253\266\346\212\200\343\203\227\343\203\255\345\260\261\346\264\273\351\203\250PR\347\224\250/105. Construct Binary Tree from Preorder and Inorder Traversal.md" "b/\347\253\266\346\212\200\343\203\227\343\203\255\345\260\261\346\264\273\351\203\250PR\347\224\250/105. Construct Binary Tree from Preorder and Inorder Traversal.md" new file mode 100644 index 0000000..f1de40e --- /dev/null +++ "b/\347\253\266\346\212\200\343\203\227\343\203\255\345\260\261\346\264\273\351\203\250PR\347\224\250/105. Construct Binary Tree from Preorder and Inorder Traversal.md" @@ -0,0 +1,120 @@ + +## 再帰による解答 +--- +### 1~3回目 +12m25s
+preorder, inorderについて考えていたためか、整理できた。 +本番でこの問題を緊張感の中で解けるかはあまり自信がない。 +変数が少なく、2~3回目において大きな変更はなし。 +時間計算量: O(N)
+空間計算量: O(N)
+ +```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_in_inorder = inorder.index(preorder[0]) + root.left = self.buildTree(preorder[1:index_in_inorder+1], inorder[:index_in_inorder]) + root.right = self.buildTree(preorder[index_in_inorder+1:], inorder[index_in_inorder+1:]) + + return root +``` + +### stackを利用した解法 +```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]) + nodes_with_index = [(root, 0, len(inorder) - 1, 0, len(preorder) - 1)] + inorder_index_map = {value: index for index, value in enumerate(inorder)} + + while nodes_with_index: + node, in_start, in_end, pre_start, pre_end = nodes_with_index.pop() + if pre_start > pre_end or in_start > in_end: + continue + + root_val = preorder[pre_start] + mid = inorder_index_map[root_val] + left_count = mid - in_start + + if left_count > 0: + left_node = TreeNode(preorder[pre_start + 1]) + node.left = left_node + nodes_with_index.append((left_node, in_start, mid - 1, pre_start + 1, pre_start + left_count)) + + if mid < in_end: + right_node = TreeNode(preorder[pre_start + left_count + 1]) + node.right = right_node + nodes_with_index.append((right_node, mid + 1, in_end, pre_start + left_count + 1, pre_end)) + + return root +``` + +right_countを定義して利用 +変数名: root_val → node_val +```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]) + nodes_with_index = [(root, 0, len(inorder) - 1, 0, len(preorder) - 1)] + inorder_index_map = {value: index for index, value in enumerate(inorder)} + + while nodes_with_index: + node, in_start, in_end, pre_start, pre_end = nodes_with_index.pop() + if pre_start > pre_end or in_start > in_end: + continue + + node_val = preorder[pre_start] + mid = inorder_index_map[node_val] + left_count = mid - in_start + right_count = in_end - mid + + if left_count > 0: + left_node = TreeNode(preorder[pre_start + 1]) + node.left = left_node + nodes_with_index.append((left_node, in_start, mid - 1, pre_start + 1, pre_start + left_count)) + + if right_count > 0: + right_node = TreeNode(preorder[pre_start + left_count + 1]) + node.right = right_node + nodes_with_index.append((right_node, mid + 1, in_end, pre_start + left_count + 1, pre_end)) + + return root +``` + +## HashMapを用いた解法 +--- +ahayashiさん、kandaさんの解答を参考に、HashMapと関数化を利用した解答も書きました。 +```python +class Solution: + def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: + def buildtree_helper(left_bound, right_bound): + nonlocal preorder_index + if left_bound >= right_bound: + return + + root_value = preorder[preorder_index] + root = TreeNode(root_value) + + inorder_index = inorder_value_to_index[root_value] + preorder_index += 1 + root.left = buildtree_helper(left_bound, inorder_index) + root.right = buildtree_helper(inorder_index + 1, right_bound) + return root + + preorder_index = 0 + inorder_value_to_index = {} + for index, value in enumerate(inorder): + inorder_value_to_index[value] = index + + return buildtree_helper(0, len(inorder)) +``` +