-
Notifications
You must be signed in to change notification settings - Fork 0
226. Invert Binary Tree #71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| ## ステップ1 | ||
| queueを使って探索し、探索中のnodeの子供をswapしていば解けそう | ||
| root = [4,2,7,1,3,6,9]で試してみる | ||
| queueに左右の順にqueueに入れることで4,2,7,1,3,6,9の順に探索できる | ||
|
|
||
| * node = 探索中のnode | ||
|
|
||
| node = 4 | ||
| root = [4,7,2,6,9,1,3] | ||
|
|
||
| node = 2 | ||
| root = [4,7,2,6,9,3,1] | ||
|
|
||
| node = 7 | ||
| root = [4,7,2,9,6,3,1] | ||
| 大丈夫そう | ||
|
|
||
| 片側がない場合を考える | ||
| [1,2] | ||
| nullptrかどうかの判定はしないで、いれかえる | ||
| [1, null, 2] | ||
|
|
||
| acceptまで15分ほど | ||
| 再帰でも同じことができそう | ||
|
|
||
| 時間計算量 O(n) | ||
| 空間計算量 O(n) 左右のどちらかに偏っていた場合 | ||
|
|
||
| ## ステップ2 | ||
| 左右のnode入れ替え部分にswapを用いる | ||
| なんとなく自分で定義していたが必要なさそう | ||
| https://en.cppreference.com/w/cpp/utility/swap.html | ||
|
|
||
| nullptrの判定位置を変えてみる | ||
| 今回の場合どちらでも良さそう | ||
|
|
||
| * step2_2 | ||
| 再帰でも解いてみる。 | ||
| inverted_leftやinverted_rightなどの一旦変数において付け替えいとエラー | ||
| =>調べてみると、直接付け替えると | ||
| node->left = invertTree(node->right); | ||
| ここで元の左側のツリー情報がなくなる。 | ||
|
|
||
| node->right = invertTree(node->left); | ||
| 元の左のnodeの情報がなくなっている. | ||
| AddressSanitizer: heap-use-after-free on addressなので解放されてしまっているのか | ||
|
|
||
| ## ステップ3 | ||
| **3回書き直しやりましょう、といっているのは、不自然なところや負荷の高いところは覚えられないからです。** | ||
|
|
||
| ## 他の方の解法 | ||
| 基本的な方針は同じ。 | ||
| queueを使う場合のnullptrかどうかの判断タイミングは、2パターンある。 | ||
| https://github.com/kzhra/Grind41/pull/6 | ||
| https://github.com/wf9a5m75/leetcode3/pull/13 | ||
|
|
||
| >大体の場合、出てきてからチェックでもいいのですが、まれに BFS で(2度入力しているかのチェックを出てきてからすると)急激に遅くなることがあります。 | ||
| 丸覚えてコードを書かないで意識する | ||
| https://github.com/huyfififi/coding-challenges/pull/6 | ||
|
|
||
| root.Left, root.Right = invertTreeRecursive(root.Right), invertTreeRecursive(root.Left) | ||
| Pythonだとこの書き方できそうだけど、C++ではサポートされていない | ||
| https://github.com/rihib/leetcode/pull/26/commits/2ef461f9770746f0279814fe302af1fe8ef0b35a | ||
|
|
||
| ## Discorなど | ||
| >細かいですが、std は standard library で C++ 誕生とともにあったのに対して、STL は standard template library という std の一部で、SGI (シリコングラフィックス)という会社が作っていたライブラリーが一部取り込まれたものです。 | ||
| 知らんかった。 | ||
| https://github.com/irohafternoon/LeetCode/pull/8 | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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* invertTree(TreeNode* root) { | ||
| if (!root) { | ||
| return nullptr; | ||
| } | ||
| queue<TreeNode*> traversing_nodes; | ||
| traversing_nodes.push(root); | ||
| while (!traversing_nodes.empty()) { | ||
| TreeNode* node = traversing_nodes.front(); | ||
| traversing_nodes.pop(); | ||
|
|
||
| TreeNode* temp = node->left; | ||
| node->left = node->right; | ||
| node->right = temp; | ||
|
|
||
| if (node->left) { | ||
| traversing_nodes.push(node->left); | ||
| } | ||
| if (node->right) { | ||
| traversing_nodes.push(node->right); | ||
| } | ||
| } | ||
|
|
||
| return root; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| /** | ||
| * 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* invertTree(TreeNode* root) { | ||
| if (!root) { | ||
| return nullptr; | ||
| } | ||
| queue<TreeNode*> traversing_nodes; | ||
| traversing_nodes.push(root); | ||
| while (!traversing_nodes.empty()) { | ||
| TreeNode* node = traversing_nodes.front(); | ||
| traversing_nodes.pop(); | ||
|
|
||
| if (!node) { | ||
| continue; | ||
| } | ||
|
|
||
| swap(node->left, node->right); | ||
|
|
||
| traversing_nodes.push(node->left); | ||
| traversing_nodes.push(node->right); | ||
| } | ||
|
|
||
| return root; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| /** | ||
| * 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* invertTree(TreeNode* node) { | ||
| if (!node) { | ||
| return nullptr; | ||
| } | ||
|
|
||
| TreeNode* inverted_left = invertTree(node->left); | ||
| TreeNode* inverted_right = invertTree(node->right); | ||
|
|
||
| node->left = inverted_right; | ||
| node->right = inverted_left; | ||
| return node; | ||
| } | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| /** | ||
| * 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* invertTree(TreeNode* node) { | ||
| if (!node) { | ||
| return nullptr; | ||
| } | ||
|
|
||
| swap(node->left, node->right); | ||
| node->left = invertTree(node->left); | ||
| node->right = invertTree(node->right); | ||
| return node; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| /** | ||
| * 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* invertTree(TreeNode* root) { | ||
| if (!root) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 個人的には脳内フローチャートをシンプルにするために、この条件分岐は入れませんね、rootがnullの場合もline 24で回収されるので。ただ、コーナーケース?を先に回収しておく派の人もいると思うので、個人的な好みかと思います。 参考までに、関連しそうなコメントを最近見かけたので残しておきます。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @huyfififi |
||
| return nullptr; | ||
| } | ||
| queue<TreeNode*> traversing_nodes; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 私はC++に疎いので変なことを言っている可能性が高いですが...LeetCode内で 参考までに、関連しそうなコメントが記憶の片隅にあったので置いておきます。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @huyfififi 実務ではないですがこちらの会の将棋AI開発をC++で挑戦しましたが名前空間を汚すことで何度かハマりました。。。 |
||
| traversing_nodes.push(root); | ||
| while (!traversing_nodes.empty()) { | ||
| TreeNode* node = traversing_nodes.front(); | ||
| traversing_nodes.pop(); | ||
|
|
||
| if (!node) { | ||
| continue; | ||
| } | ||
|
|
||
| swap(node->left, node->right); | ||
|
|
||
| traversing_nodes.push(node->left); | ||
| traversing_nodes.push(node->right); | ||
| } | ||
|
|
||
| return root; | ||
| } | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| /** | ||
| * 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) {} | ||
| * }; | ||
| */ | ||
| #include <queue> | ||
|
|
||
| class Solution { | ||
| public: | ||
| TreeNode* invertTree(TreeNode* root) { | ||
| std::queue<TreeNode*> traversing_nodes; | ||
| traversing_nodes.push(root); | ||
| while (!traversing_nodes.empty()) { | ||
| TreeNode* node = traversing_nodes.front(); | ||
| traversing_nodes.pop(); | ||
|
|
||
| if (!node) { | ||
| continue; | ||
| } | ||
|
|
||
| std::swap(node->left, node->right); | ||
|
|
||
| traversing_nodes.push(node->left); | ||
| traversing_nodes.push(node->right); | ||
| } | ||
|
|
||
| return root; | ||
| } | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::swap(node->left, node->right); node->left = invertTree(node->left); node->right = invertTree(node->right);でもよいと思います。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nodchip
レビューありがとうございます。step2_3に追加しました。