From 278be41ee08b01b192f226d9582530573bb38808 Mon Sep 17 00:00:00 2001 From: Ryotaro Kurita Date: Sat, 11 Jan 2025 17:33:57 +0900 Subject: [PATCH 1/4] finish --- 776.SplitBST/memo.md | 54 ++++++++++++++++++++++++++++++++++++++ 776.SplitBST/recursive.cpp | 30 +++++++++++++++++++++ 776.SplitBST/step1.cpp | 39 +++++++++++++++++++++++++++ 776.SplitBST/step2.cpp | 43 ++++++++++++++++++++++++++++++ 776.SplitBST/step3.cpp | 38 +++++++++++++++++++++++++++ 5 files changed, 204 insertions(+) create mode 100644 776.SplitBST/memo.md create mode 100644 776.SplitBST/recursive.cpp create mode 100644 776.SplitBST/step1.cpp create mode 100644 776.SplitBST/step2.cpp create mode 100644 776.SplitBST/step3.cpp diff --git a/776.SplitBST/memo.md b/776.SplitBST/memo.md new file mode 100644 index 0000000..221a748 --- /dev/null +++ b/776.SplitBST/memo.md @@ -0,0 +1,54 @@ +## ステップ1 +まず思いついたのはrootとは別に2つ新たにnodeを用意して、 +targetより小さいものと大きいものをそれぞれのツリーを作りそれらをvectorに入れて返却する。 + +一旦プログラムを書いて上手く動かなかったので、答えを確認し1.5hほどでacceptできた。 +理解出来ていなかった箇所はループの小さい側、大きい側のそれぞれに2回目以降に紐付ける場合の動き。 +root = [4,2,6,1,3,5,7], target = 2の場合 +val = 4 smaller_node [] larger_node [4,6,5,7] +val = 2 smaller_node [2, 1] larger_node [4,6,5,7] +val = 3 smaller_node [2, 1] larger_node [4,3,6,5,7] // 探索終了 +ここで3をどのように大きい側に繋ぐのかは答えを確認した。 + +3つのnodeを使っているんのでそれぞれの値をどう更新するのか理解するのに時間がかかった。 + +時間計算量 +O(n) +左右に偏っている場合 + +空間計算量 +O(1) + +## ステップ2 +・変数名の修正 +・理解するためにコメントを追記 +・if文を反転 + +再帰でも実装recusive.cpp +構造体を使いたかったが、返却値に合わせて型変換を行う必要があるので今回はそのまま + +## ステップ3 +**3回書き直しやりましょう、といっているのは、不自然なところや負荷の高いところは覚えられないからです。** + +## 他の方の解法 +gotoさんは再帰の解法を用いている。 + +>手作業時にいきなりプログラムありきで解き方を考えている気がする +これは自分も本当にそうでかつ、ロジックから答えを導くのではなく答えからロジックを導こうとしている。 + +https://github.com/goto-untrapped/Arai60/pull/54/commits/570e2c2f1ee6ddcbdeaead4c40dbb2fb2a25d817 + +型名を決めるときの注意点 +>型は何かをできなくするための制限なので、何をできないようにしたかと、そのメリットのバランスで決めるもの + +>分割後のtreeはleft, rightよりsmaller, largerのほうが性質の違いが表現できていていいと思った +>戻り値がleft, rightだとどっちから見てleft, rightなのかわからなくなりそうと思った +小さい側(大きい側)のツリーにもleftとrightが存在するためsmaller largerが良さそう +https://github.com/Yoshiki-Iwasa/Arai60/pull/41 + +>2 個連続で入れるのは、トップレベルの関数や変数の間だけが良いと思います。 +知らなかった。 +https://github.com/Mike0121/LeetCode/pull/16 + +## Discordなど + diff --git a/776.SplitBST/recursive.cpp b/776.SplitBST/recursive.cpp new file mode 100644 index 0000000..82233a7 --- /dev/null +++ b/776.SplitBST/recursive.cpp @@ -0,0 +1,30 @@ +/** + * 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: + vector splitBST(TreeNode* node, int target) { + if (!node) { + return {nullptr, nullptr}; + } + + if (node->val <= target) { + // 左側はtargetより小さいので右側を探索する + vector right_child = splitBST(node->right, target); + node->right = right_child[0]; + return {node, right_child[1]} + } else { + vector left_child = splitBST(node->left, target); + node->left = left_child[1]; + return {left_child[0], node} + } + } +}; diff --git a/776.SplitBST/step1.cpp b/776.SplitBST/step1.cpp new file mode 100644 index 0000000..88bdcaa --- /dev/null +++ b/776.SplitBST/step1.cpp @@ -0,0 +1,39 @@ +/** + * 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: + vector splitBST(TreeNode* root, int target) { + TreeNode* node = root; + + TreeNode* smaller_head = new TreeNode(); + TreeNode* smaller_node = smaller_head; + + TreeNode* larger_head = new TreeNode(); + TreeNode* larger_node = larger_head; + + while (node) { + if (node->val <= target) { + smaller_node->right = node; + smaller_node = smaller_node->right; + node = node->right; + smaller_node->right = nullptr; + } else { + larger_node->left = node; + larger_node = larger_node->left; + node = node->left; + larger_node->left = nullptr; + } + } + + return {smaller_head->right, larger_head->left}; + } +}; diff --git a/776.SplitBST/step2.cpp b/776.SplitBST/step2.cpp new file mode 100644 index 0000000..c202968 --- /dev/null +++ b/776.SplitBST/step2.cpp @@ -0,0 +1,43 @@ +/** + * 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: + vector splitBST(TreeNode* root, int target) { + TreeNode* node = root; + + TreeNode* smaller_head = new TreeNode(); + TreeNode* smaller = smaller_head; + + TreeNode* bigger_head = new TreeNode(); + TreeNode* larger = bigger_head; + + while (node) { + if (node->val > target) { + // 現在のnodeの値の方が小さいので左側に紐づける + larger->left = node; + larger = larger->left; + // 現在のnodeの値の方が大きいので左側に探索を進める + node = node->left; + larger->left = nullptr; + } else { + // 現在のnodeの値の方が大きいので右側に紐づける + smaller->right = node; + smaller = smaller->right; + // 大きい数字が含まれているので右側に探索を進める + node = node->right; + smaller->right = nullptr; + } + } + + return {smaller_head->right, bigger_head->left}; + } +}; diff --git a/776.SplitBST/step3.cpp b/776.SplitBST/step3.cpp new file mode 100644 index 0000000..2ddd019 --- /dev/null +++ b/776.SplitBST/step3.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: + vector splitBST(TreeNode* root, int target) { + TreeNode* node = root; + TreeNode* smaller_head = new TreeNode(); + auto smaller = smaller_head; + + TreeNode* larger_head = new TreeNode(); + auto larger = larger_head; + + while (node) { + if (node->val > target) { + larger->left = node; + larger = larger->left; + node = node->left; + larger->left = nullptr; + } else { + smaller->right = node; + smaller = smaller->right; + node = node->right; + smaller->right = nullptr; + } + } + + return {smaller_head->right, larger_head->left}; + } +}; From efce3c9c561d9a6dafb02638ee0fe143ef267bf7 Mon Sep 17 00:00:00 2001 From: Ryotaro Kurita Date: Sat, 11 Jan 2025 17:49:35 +0900 Subject: [PATCH 2/4] mod comment --- 776.SplitBST/step2.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/776.SplitBST/step2.cpp b/776.SplitBST/step2.cpp index c202968..93ab195 100644 --- a/776.SplitBST/step2.cpp +++ b/776.SplitBST/step2.cpp @@ -22,14 +22,14 @@ class Solution { while (node) { if (node->val > target) { - // 現在のnodeの値の方が小さいので左側に紐づける + // 現在のnodeの値の方が小さいのでnodeを左側に紐づける larger->left = node; larger = larger->left; - // 現在のnodeの値の方が大きいので左側に探索を進める + // 小さい数字が含まれているので左側に探索を進める node = node->left; larger->left = nullptr; } else { - // 現在のnodeの値の方が大きいので右側に紐づける + // 現在のnodeの値の方が大きいのでnodeを右側に紐づける smaller->right = node; smaller = smaller->right; // 大きい数字が含まれているので右側に探索を進める From 2998a0259f422b23e9a0e42255940fff15e1b3c7 Mon Sep 17 00:00:00 2001 From: Ryotaro Kurita Date: Mon, 13 Jan 2025 22:45:05 +0900 Subject: [PATCH 3/4] mod reflecting review --- 776.SplitBST/loop_and_recursion.cpp | 40 +++++++++++++++++++++++++++++ 776.SplitBST/step4.cpp | 38 +++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 776.SplitBST/loop_and_recursion.cpp create mode 100644 776.SplitBST/step4.cpp diff --git a/776.SplitBST/loop_and_recursion.cpp b/776.SplitBST/loop_and_recursion.cpp new file mode 100644 index 0000000..de9ac0c --- /dev/null +++ b/776.SplitBST/loop_and_recursion.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: + vector splitBST(TreeNode* root, int target) { + TreeNode* left; + TreeNode* right; + + splitBSTHelper(root, target, left, right); + return {left, right}; + } + +private: + void splitBSTHelper(TreeNode* node, int target, TreeNode*& left, TreeNode*& right) { + if (!node) { + return; + } + + if (node->val > target) { + right = node; + node = node->left; + left = nullptr; + splitBSTHelper(node, target, left, right->left); + } else { + left = node; + node = node->right; + right = nullptr; + splitBSTHelper(node, target, left->right, right); + } + } +}; diff --git a/776.SplitBST/step4.cpp b/776.SplitBST/step4.cpp new file mode 100644 index 0000000..cd9a3db --- /dev/null +++ b/776.SplitBST/step4.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: + vector splitBST(TreeNode* root, int target) { + TreeNode* node = root; + TreeNode* smaller_root = new TreeNode(); + auto smaller = smaller_root; + + TreeNode* larger_root = new TreeNode(); + auto larger = larger_root; + + while (node) { + if (node->val > target) { + larger->left = node; + larger = larger->left; + node = node->left; + larger->left = nullptr; + } else { + smaller->right = node; + smaller = smaller->right; + node = node->right; + smaller->right = nullptr; + } + } + + return {smaller_root->right, larger_root->left}; + } +}; From 9b243c6379da2bc84974249e637b5bb5f4e431e7 Mon Sep 17 00:00:00 2001 From: Ryotaro Kurita Date: Wed, 15 Jan 2025 23:20:22 +0900 Subject: [PATCH 4/4] mod comment --- 776.SplitBST/step2.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/776.SplitBST/step2.cpp b/776.SplitBST/step2.cpp index 93ab195..a4508f7 100644 --- a/776.SplitBST/step2.cpp +++ b/776.SplitBST/step2.cpp @@ -22,14 +22,16 @@ class Solution { while (node) { if (node->val > target) { - // 現在のnodeの値の方が小さいのでnodeを左側に紐づける + // 現在のnodeの値の方が小さいので、 + // largerの左側に現在のnodeを紐づける larger->left = node; larger = larger->left; // 小さい数字が含まれているので左側に探索を進める node = node->left; larger->left = nullptr; } else { - // 現在のnodeの値の方が大きいのでnodeを右側に紐づける + // 現在のnodeの値の方が大きいので、 + // smallerの右側にnodeを右側に紐づける smaller->right = node; smaller = smaller->right; // 大きい数字が含まれているので右側に探索を進める