From 71d16952d6b4e0f8b375eb89f21901bf26eb2148 Mon Sep 17 00:00:00 2001 From: Ryotaro Kurita Date: Wed, 28 Aug 2024 00:30:24 +0900 Subject: [PATCH 1/3] finish --- .../hash_map.cpp | 40 ++++++++++++++++ .../memo.md | 48 +++++++++++++++++++ .../step1.cpp | 38 +++++++++++++++ .../step2.cpp | 31 ++++++++++++ .../step3.cpp | 31 ++++++++++++ .../step4.cpp | 47 ++++++++++++++++++ 6 files changed, 235 insertions(+) create mode 100644 105.ConstructBinaryTreefromPreorderandInorderTraversal/hash_map.cpp create mode 100644 105.ConstructBinaryTreefromPreorderandInorderTraversal/memo.md create mode 100644 105.ConstructBinaryTreefromPreorderandInorderTraversal/step1.cpp create mode 100644 105.ConstructBinaryTreefromPreorderandInorderTraversal/step2.cpp create mode 100644 105.ConstructBinaryTreefromPreorderandInorderTraversal/step3.cpp create mode 100644 105.ConstructBinaryTreefromPreorderandInorderTraversal/step4.cpp diff --git a/105.ConstructBinaryTreefromPreorderandInorderTraversal/hash_map.cpp b/105.ConstructBinaryTreefromPreorderandInorderTraversal/hash_map.cpp new file mode 100644 index 0000000..0facb70 --- /dev/null +++ b/105.ConstructBinaryTreefromPreorderandInorderTraversal/hash_map.cpp @@ -0,0 +1,40 @@ +/** + * 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: + TreeNode* buildTree(vector& preorder, vector& inorder) { + for (int i = 0; i < inorder.size(); i++) { + inorder_value_to_index[inorder[i]] = i; + } + + return BuildTreeHelper(0, inorder.size(), preorder); + } + +private: + int preorder_index = 0; + unordered_map inorder_value_to_index; + + TreeNode* BuildTreeHelper(int left_bound, int right_bound, vector& preorder) { + if (left_bound >= right_bound) { + return nullptr; + } + + int value = preorder[preorder_index]; + TreeNode* node = new TreeNode(value); + + int inorder_index = inorder_value_to_index[value]; + preorder_index++; + node->left = BuildTreeHelper(left_bound, inorder_index, preorder); + node->right = BuildTreeHelper(inorder_index + 1, right_bound, preorder); + return node; + } +}; diff --git a/105.ConstructBinaryTreefromPreorderandInorderTraversal/memo.md b/105.ConstructBinaryTreefromPreorderandInorderTraversal/memo.md new file mode 100644 index 0000000..2a5924a --- /dev/null +++ b/105.ConstructBinaryTreefromPreorderandInorderTraversal/memo.md @@ -0,0 +1,48 @@ +## ステップ1 +inorderもしくはpreorderの要素を一方のKeyとして +インデックスを取得することで何かできないか。。。 +preorderの最初の3つの要素がrootとその左右になるのか + +15分考えて分からなかったので、答えを見ないでそれぞれpreorderとinorderはどういったものなのか確認 +preorder traversal +https://www.geeksforgeeks.org/preorder-traversal-of-binary-tree/ +inorder traversal +https://www.geeksforgeeks.org/inorder-traversal-of-binary-tree/ + +ここで再挑戦 +15分考えて分からなかったので回答確認 +https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/solutions/5632202/video-2-solutions-with-o-n-2-and-o-n-time/ +preorderの要素からinorderのindexを取得して、そのindexの左側が左のnodeに右側が右のnodeに紐づく +これはinorderが常に左側を優先してトラバースするため + +時間計算量 +O(n^2) +eraseとindexを探すforループの部分でそれぞれO(n) +上記を要素の数だけ再帰的にn回呼び出すため + +空間計算量 +O(n^2) +左右それぞれのvectorを呼び出す部分がO(n) +上記を要素の数だけ再帰的にn回呼び出すため + +## ステップ2 +・イテレーターの定義方法変更 + forループでindexを見つけてからiteratorに変換していたがfind関数が存在していた + + +## 他の解法 +hash_mapを用いた解法もある +https://github.com/Mike0121/LeetCode/pull/12/commits/d4ccd11c98bbb8982422a7588dee7fddcb062ff7?short_path=37c38ad#diff-37c38adee77a00d4840ea0049203ac45f60966aa4ad1c8b6d80b1dc78d6def37 +step2に似ているが、vectorを再帰的に呼び出すのではなく +index(int)をを渡して再帰を行うので処理が軽い + +hash_mapでなくともmapでも可能 + +## Discordや他のPRなど +・自分の解法と違ってpreorder側も新たに作成している + 自分のは破壊的変更を行なっているので元のpreorderは使えない + preorder側をindex渡して管理 + step4.cppに実装 +https://github.com/TORUS0818/leetcode/pull/31/commits/24492ff4388f596583de9dbf504f7a010a554fc7 +https://github.com/kazukiii/leetcode/pull/30#discussion_r1685735022 +https://github.com/Yoshiki-Iwasa/Arai60/pull/33 diff --git a/105.ConstructBinaryTreefromPreorderandInorderTraversal/step1.cpp b/105.ConstructBinaryTreefromPreorderandInorderTraversal/step1.cpp new file mode 100644 index 0000000..8983f95 --- /dev/null +++ b/105.ConstructBinaryTreefromPreorderandInorderTraversal/step1.cpp @@ -0,0 +1,38 @@ +/** + * 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: + TreeNode* buildTree(vector& preorder, vector& inorder) { + if (!inorder.empty()) { + int value = preorder[0]; + preorder.erase(preorder.begin()); + + TreeNode* node = new TreeNode(value); + + int index; + for (int i = 0; i < inorder.size(); i++) { + if (inorder[i] == value) { + index = i; + } + } + vector::iterator position = inorder.begin() + index; + vector left_inorder(inorder.begin(), position); + vector right_inorder(position + 1, inorder.end()); + + node->left = buildTree(preorder, left_inorder); + node->right = buildTree(preorder, right_inorder); + + return node; + } + return nullptr; + } +}; diff --git a/105.ConstructBinaryTreefromPreorderandInorderTraversal/step2.cpp b/105.ConstructBinaryTreefromPreorderandInorderTraversal/step2.cpp new file mode 100644 index 0000000..c03ef10 --- /dev/null +++ b/105.ConstructBinaryTreefromPreorderandInorderTraversal/step2.cpp @@ -0,0 +1,31 @@ +/** + * 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: + TreeNode* buildTree(vector& preorder, vector& inorder) { + if (!inorder.empty()) { + int value = preorder[0]; + preorder.erase(preorder.begin()); + + TreeNode* node = new TreeNode(value); + auto position = find(inorder.begin(), inorder.end(), value); + vector left_inorder(inorder.begin(), position); + vector right_inorder(position + 1, inorder.end()); + + node->left = buildTree(preorder, left_inorder); + node->right = buildTree(preorder, right_inorder); + + return node; + } + return nullptr; + } +}; diff --git a/105.ConstructBinaryTreefromPreorderandInorderTraversal/step3.cpp b/105.ConstructBinaryTreefromPreorderandInorderTraversal/step3.cpp new file mode 100644 index 0000000..c03ef10 --- /dev/null +++ b/105.ConstructBinaryTreefromPreorderandInorderTraversal/step3.cpp @@ -0,0 +1,31 @@ +/** + * 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: + TreeNode* buildTree(vector& preorder, vector& inorder) { + if (!inorder.empty()) { + int value = preorder[0]; + preorder.erase(preorder.begin()); + + TreeNode* node = new TreeNode(value); + auto position = find(inorder.begin(), inorder.end(), value); + vector left_inorder(inorder.begin(), position); + vector right_inorder(position + 1, inorder.end()); + + node->left = buildTree(preorder, left_inorder); + node->right = buildTree(preorder, right_inorder); + + return node; + } + return nullptr; + } +}; diff --git a/105.ConstructBinaryTreefromPreorderandInorderTraversal/step4.cpp b/105.ConstructBinaryTreefromPreorderandInorderTraversal/step4.cpp new file mode 100644 index 0000000..f15c8d4 --- /dev/null +++ b/105.ConstructBinaryTreefromPreorderandInorderTraversal/step4.cpp @@ -0,0 +1,47 @@ +/** + * 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: + TreeNode* buildTree(vector& preorder, vector& inorder) { + return BuildTreeHelper(preorder, 0, preorder.size(), inorder, 0, + inorder.size()); + } + +private: + TreeNode* BuildTreeHelper(const vector& preorder, int preorder_start, int preorder_end, + const vector& inorder, int inorder_start, int inorder_end) { + if (preorder_start >= preorder_end || inorder_start >= inorder_end) { + return nullptr; + } + + int value = preorder[preorder_start]; + TreeNode* node = new TreeNode(value); + + int position = FindSeparatingPosition(inorder, inorder_start, inorder_end, value); + + int left_tree_size = position - inorder_start + 1; + node->left = BuildTreeHelper(preorder, preorder_start + 1, preorder_start + left_tree_size, + inorder, inorder_start, position); + node->right = BuildTreeHelper(preorder, preorder_start + left_tree_size, preorder_end, + inorder, position + 1, inorder_end); + return node; + } + + int FindSeparatingPosition(const vector& inorder, int start, int end, int value) { + for (int i = start; i < end; ++i) { + if (inorder[i] == value) { + return i; + } + } + return -1; + } +}; \ No newline at end of file From 38a43254bdc4625c8ab9680f7a517ccceef2c562 Mon Sep 17 00:00:00 2001 From: Ryotaro Kurita Date: Thu, 29 Aug 2024 22:05:30 +0900 Subject: [PATCH 2/3] add modfied files --- .../hash_map_step2.cpp | 40 ++++++++++++++++ .../step5.cpp | 31 ++++++++++++ .../step6.cpp | 47 +++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 105.ConstructBinaryTreefromPreorderandInorderTraversal/hash_map_step2.cpp create mode 100644 105.ConstructBinaryTreefromPreorderandInorderTraversal/step5.cpp create mode 100644 105.ConstructBinaryTreefromPreorderandInorderTraversal/step6.cpp diff --git a/105.ConstructBinaryTreefromPreorderandInorderTraversal/hash_map_step2.cpp b/105.ConstructBinaryTreefromPreorderandInorderTraversal/hash_map_step2.cpp new file mode 100644 index 0000000..b04af9f --- /dev/null +++ b/105.ConstructBinaryTreefromPreorderandInorderTraversal/hash_map_step2.cpp @@ -0,0 +1,40 @@ +/** + * 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: + TreeNode* buildTree(vector& preorder, vector& inorder) { + for (int i = 0; i < inorder.size(); i++) { + inorder_value_to_index[inorder[i]] = i; + } + + int preorder_index = 0; + return BuildTreeHelper(0, inorder.size(), preorder, preorder_index); + } + +private: + unordered_map inorder_value_to_index; + + TreeNode* BuildTreeHelper(int left_bound, int right_bound, vector& preorder, int& preorder_index) { + if (left_bound >= right_bound) { + return nullptr; + } + + int value = preorder[preorder_index]; + TreeNode* node = new TreeNode(value); + + int inorder_index = inorder_value_to_index[value]; + preorder_index++; + node->left = BuildTreeHelper(left_bound, inorder_index, preorder, preorder_index); + node->right = BuildTreeHelper(inorder_index + 1, right_bound, preorder, preorder_index); + return node; + } +}; diff --git a/105.ConstructBinaryTreefromPreorderandInorderTraversal/step5.cpp b/105.ConstructBinaryTreefromPreorderandInorderTraversal/step5.cpp new file mode 100644 index 0000000..7786c76 --- /dev/null +++ b/105.ConstructBinaryTreefromPreorderandInorderTraversal/step5.cpp @@ -0,0 +1,31 @@ +/** + * 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: + TreeNode* buildTree(vector& preorder, vector& inorder) { + if (inorder.empty()) { + return nullptr; + } + int value = preorder[0]; + preorder.erase(preorder.begin()); + + TreeNode* node = new TreeNode(value); + auto position = find(inorder.begin(), inorder.end(), value); + vector left_inorder(inorder.begin(), position); + vector right_inorder(position + 1, inorder.end()); + + node->left = buildTree(preorder, left_inorder); + node->right = buildTree(preorder, right_inorder); + + return node; + } +}; diff --git a/105.ConstructBinaryTreefromPreorderandInorderTraversal/step6.cpp b/105.ConstructBinaryTreefromPreorderandInorderTraversal/step6.cpp new file mode 100644 index 0000000..c6dacb6 --- /dev/null +++ b/105.ConstructBinaryTreefromPreorderandInorderTraversal/step6.cpp @@ -0,0 +1,47 @@ +/** + * 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: + TreeNode* buildTree(vector& preorder, vector& inorder) { + return BuildTreeHelper(preorder, 0, inorder, 0, inorder.size()); + } + +private: + TreeNode* BuildTreeHelper(const vector& preorder, int preorder_start, + const vector& inorder, int inorder_start, int tree_size) { + if (tree_size <= 0) { + return nullptr; + } + + int value = preorder[preorder_start]; + TreeNode* node = new TreeNode(value); + + int inorder_root_index = FindSeparatingIndex(inorder, inorder_start, inorder_start + tree_size, value); + int left_tree_size = inorder_root_index - inorder_start; + + node->left = BuildTreeHelper(preorder, preorder_start + 1, + inorder, inorder_start, left_tree_size); + + node->right = BuildTreeHelper(preorder, preorder_start + 1 + left_tree_size, + inorder, inorder_root_index + 1, tree_size - left_tree_size - 1); + return node; + } + + int FindSeparatingIndex(const vector& inorder, int start, int end, int value) { + for (int i = start; i < end; ++i) { + if (inorder[i] == value) { + return i; + } + } + return -1; + } +}; From 45559d5e166062843e12e3cfeb69dac1c403dd2e Mon Sep 17 00:00:00 2001 From: Ryotaro Kurita Date: Tue, 10 Jun 2025 23:26:41 +0900 Subject: [PATCH 3/3] added step7 --- .../step7.cpp | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 105.ConstructBinaryTreefromPreorderandInorderTraversal/step7.cpp diff --git a/105.ConstructBinaryTreefromPreorderandInorderTraversal/step7.cpp b/105.ConstructBinaryTreefromPreorderandInorderTraversal/step7.cpp new file mode 100644 index 0000000..d5b7c6a --- /dev/null +++ b/105.ConstructBinaryTreefromPreorderandInorderTraversal/step7.cpp @@ -0,0 +1,50 @@ +/** + * 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: + TreeNode* buildTree(vector& preorder, vector& inorder) { + if (preorder.empty() || inorder.empty()) { + return nullptr; + } + int preorder_index = 0; + return BuildTreeHelper(preorder, inorder, preorder_index, 0, inorder.size() - 1); + } + +private: + TreeNode* BuildTreeHelper(const vector& preorder, const vector& inorder, + int& preorder_index, int left, int right) { + if (left > right) { + return nullptr; + } + // preorderはroot left right の順なので、 + // 最初の要素が現在の部分木の root + int root_value = preorder[preorder_index]; + TreeNode* node = new TreeNode(root_value); + + // inorderではleft root rightの順に並ぶので + // root の位置で左右に分けられる + int division_index = 0; + for (int i = 0; i < inorder.size(); i++) { + if (inorder[i] == root_value) { + division_index = i; + break; + } + } + // preorder_indexを進めることで、 + // 次の部分木のrootを preorderから取得できる + // 引数は参照渡しなので、左部分木の再帰での更新が右部分木の再帰にも反映される + preorder_index++; + node->left = BuildTreeHelper(preorder, inorder, preorder_index, left, division_index - 1); + node->right = BuildTreeHelper(preorder, inorder, preorder_index, division_index + 1, right); + return node; + } +};