diff --git a/0105-construct-binary-tree-from-preorder-and-inorder-traversal/memo.md b/0105-construct-binary-tree-from-preorder-and-inorder-traversal/memo.md new file mode 100644 index 0000000..f32e291 --- /dev/null +++ b/0105-construct-binary-tree-from-preorder-and-inorder-traversal/memo.md @@ -0,0 +1,11 @@ +### step1 + +なんとか自力で実装。preorderの一番左は必ずrootになることをベースに、DFSしながらpreorder,inorderを共に分割していきながら木を構築したが添え字管理がかなり煩雑になった。 + +### step2 + +煩雑なindex管理をChatGPTに直してもらった。 + +### step3 + +3回通すまで書き直し。 diff --git a/0105-construct-binary-tree-from-preorder-and-inorder-traversal/step1.cpp b/0105-construct-binary-tree-from-preorder-and-inorder-traversal/step1.cpp new file mode 100644 index 0000000..ba9ea28 --- /dev/null +++ b/0105-construct-binary-tree-from-preorder-and-inorder-traversal/step1.cpp @@ -0,0 +1,56 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode() : val(0), left(nullptr), right(nullptr) {} + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} + * }; + */ +class Solution { +public: + void traverse( + TreeNode* tree, + const vector& preorder, + const vector& inorder, + int pre_left, + int pre_right, + int in_left, + int in_right + ) { + auto it = find(inorder.begin() + in_left, inorder.begin() + in_right, preorder[pre_left]); + if (it - inorder.begin() != in_left) { + tree->left = new TreeNode(preorder[pre_left + 1]); + traverse( + tree->left, + preorder, + inorder, + pre_left + 1, + pre_left + it - (inorder.begin() + in_left), + in_left, + it - inorder.begin() - 1 + ); + } + if (it - inorder.begin() != in_right) { + tree->right = new TreeNode(preorder[pre_left + it - (inorder.begin() + in_left) + 1]); + traverse( + tree->right, + preorder, + inorder, + pre_left + it - (inorder.begin() + in_left) + 1, + pre_right, + it - inorder.begin() + 1, + in_right + ); + } + } + + TreeNode* buildTree(vector& preorder, vector& inorder) { + TreeNode* tree = new TreeNode(preorder[0]); + int size = preorder.size(); + traverse(tree, preorder, inorder, 0, size - 1, 0, size - 1); + return tree; + } +}; diff --git a/0105-construct-binary-tree-from-preorder-and-inorder-traversal/step2.cpp b/0105-construct-binary-tree-from-preorder-and-inorder-traversal/step2.cpp new file mode 100644 index 0000000..2358c7c --- /dev/null +++ b/0105-construct-binary-tree-from-preorder-and-inorder-traversal/step2.cpp @@ -0,0 +1,45 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode() : val(0), left(nullptr), right(nullptr) {} + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} + * }; + */ +class Solution { +public: + unordered_map inorder_val_to_index; + + TreeNode* build( + const vector& preorder, + int preL, + int preR, + int inL + ) { + if (preL > preR) { + return nullptr; + } + + int rootVal = preorder[preL]; + int rootIdx = inorder_val_to_index[rootVal]; + int leftSize = rootIdx - inL; + + TreeNode* root = new TreeNode(rootVal); + + root->left = build(preorder, preL + 1, preL + leftSize, inL); + root->right = build(preorder, preL + leftSize + 1, preR, rootIdx + 1); + + return root; + } + + TreeNode* buildTree(vector& preorder, vector& inorder) { + for (int i = 0; i < inorder.size(); i++) { + inorder_val_to_index[inorder[i]] = i; + } + + return build(preorder, 0, preorder.size() - 1, 0); + } +}; diff --git a/0105-construct-binary-tree-from-preorder-and-inorder-traversal/step3.cpp b/0105-construct-binary-tree-from-preorder-and-inorder-traversal/step3.cpp new file mode 100644 index 0000000..2358c7c --- /dev/null +++ b/0105-construct-binary-tree-from-preorder-and-inorder-traversal/step3.cpp @@ -0,0 +1,45 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode() : val(0), left(nullptr), right(nullptr) {} + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} + * }; + */ +class Solution { +public: + unordered_map inorder_val_to_index; + + TreeNode* build( + const vector& preorder, + int preL, + int preR, + int inL + ) { + if (preL > preR) { + return nullptr; + } + + int rootVal = preorder[preL]; + int rootIdx = inorder_val_to_index[rootVal]; + int leftSize = rootIdx - inL; + + TreeNode* root = new TreeNode(rootVal); + + root->left = build(preorder, preL + 1, preL + leftSize, inL); + root->right = build(preorder, preL + leftSize + 1, preR, rootIdx + 1); + + return root; + } + + TreeNode* buildTree(vector& preorder, vector& inorder) { + for (int i = 0; i < inorder.size(); i++) { + inorder_val_to_index[inorder[i]] = i; + } + + return build(preorder, 0, preorder.size() - 1, 0); + } +};