-
Notifications
You must be signed in to change notification settings - Fork 0
Create 104. Maximum Depth of Binary Tree #29
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,150 @@ | ||
| # [104. Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/description/) | ||
| ## Step1 | ||
| ### 問題意図の考察 | ||
| - 問題文の確認 | ||
| - 与えられた二分木の根に対して、最大深度を返す。 | ||
| - 二分木の最大深度 = root nodeから最も遠い leaf nodeまで | ||
|
|
||
| - 制約の確認 | ||
| - nodeの数は、0 ~ 10^4 | ||
| - 各nodeの値は、-100 ~ 100 | ||
|
|
||
| - 問題意図 | ||
| - nodeの数に注意 | ||
| - 左部分ぽい所の深さを求める | ||
| - 右部分ぽい所の深さを求める | ||
| - そのうち大きい方を返す | ||
|
|
||
| ### 解法を考える。 | ||
| - DFS | ||
| - 再帰で返す方法 シンプルで良さそう | ||
| - BFS | ||
| - 何段階のレベルがあるか分かればよい | ||
| - level1 -> level2 -> level3 | ||
|
|
||
| 初回の回答 | ||
| ```cpp | ||
| #include <algorithm> | ||
|
|
||
| class Solution { | ||
| public: | ||
| int maxDepth(TreeNode* root) { | ||
| if (root == nullptr) { | ||
| return 0; | ||
| } | ||
|
|
||
| int left = maxDepth(root->left); | ||
| int right = maxDepth(root->right); | ||
|
|
||
| return std::max(left, right) + 1; | ||
| } | ||
| }; | ||
|
|
||
| ``` | ||
|
|
||
| ### コメント | ||
| - TreeNode の定義内で、left, rightが使用されているので、命名が良くないかな。 | ||
| - left_depth, right_depthくらいが分かりやすいかもしれない | ||
| - if (root = nullptr) に関して | ||
| - https://github.com/nktr-cp/leetcode/pull/22/files#diff-d16010dc25fbb50a03680c436bbb0d90f462bf27b3aa26421f1df94d5f15aa15 | ||
| - 他の方のcodeで、if (!root) という記述があった。違いを少し考えた。 | ||
| - ポインタが null -> false -> true (if条件成立) | ||
| - root を nullptrと比較 | ||
|
|
||
| ```cpp | ||
| #include <algorithm> | ||
|
|
||
| class Solution { | ||
| public: | ||
| int maxDepth(TreeNode* root) { | ||
| if (!root) { | ||
| return 0; | ||
| } | ||
|
|
||
| int left_depth = maxDepth(root->left); | ||
| int right_depth = maxDepth(root->right); | ||
|
|
||
| return std::max(left_depth, right_depth) + 1; | ||
| } | ||
| }; | ||
|
|
||
| ``` | ||
|
|
||
| ## Step2 *2段階目、自然な書き方を考えて整理する | ||
| - 改善点 | ||
| - https://github.com/nktr-cp/leetcode/pull/22/files#diff-d16010dc25fbb50a03680c436bbb0d90f462bf27b3aa26421f1df94d5f15aa15 | ||
| - もっとシンプルに書いている例があった。 | ||
| ```cpp | ||
| class Solution { | ||
| public: | ||
| int maxDepth(TreeNode* root) { | ||
| if (root == nullptr) { | ||
| return 0; | ||
| } | ||
| return std::max(maxDepth(root->left), maxDepth(root->right)) + 1; | ||
|
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. この書き方と,Step1の書き方のどちらが良いか(1行にまとめる処理の最大数はどれくらいか)は好みが分かれるところだと思います.私はこのくらいならStep2の方がわかりやすいと感じます. |
||
| } | ||
| }; | ||
|
|
||
| ``` | ||
|
|
||
| - 他の方のコードを読む | ||
| - 前述:https://github.com/nktr-cp/leetcode/pull/22/files | ||
| - https://github.com/5103246/LeetCode_Arai60/pull/20/commits/cb2a3f1f447cd59e8d6ac1e2910262a6a05ca7b4 | ||
| - https://github.com/5ky7/arai60/pull/20/commits/6c2084a4cf7e5760e2d5130518cda59496833be6 | ||
| - https://github.com/ryosuketc/leetcode_arai60/pull/21/commits/333e716a565c4c0cdb627e8d378410010fd64588 | ||
| - https://github.com/nanae772/leetcode-arai60/pull/21/commits/9cc3d36c42d10bef83b97d017a73b65d5c0e52af | ||
| > 木の高さと深さの違いがよく分かってなかったが | ||
| > nodeの高さ=nodeから最も遠い葉までのパスの長さ | ||
| > 木の高さ=rootから最も遠い葉までのパスの長さ | ||
| > nodeの深さ=nodeからrootまでのパスの長さ | ||
| - ここはしっかりと押さえておきたい | ||
| - (要復習) | ||
| - C/C++だとポインタを持てるのでそのポインタを通じて親への伝播が自動的に行える。 | ||
| - https://discord.com/channels/1084280443945353267/1227073733844406343/1236324993839792149 | ||
|
|
||
| - BFS(Breadth-First Search)の書き方 | ||
| - 分からなかったので、参照 | ||
| - https://cp-algorithms.com/graph/breadth-first-search.html | ||
| - https://www.geeksforgeeks.org/dsa/breadth-first-search-or-bfs-for-a-graph/ | ||
|
|
||
| ```cpp | ||
| class Solution { | ||
| public: | ||
| int maxDepth(TreeNode* root) { | ||
| if (root == nullptr) { | ||
| return 0; | ||
| } | ||
|
|
||
| std::queue<TreeNode*> q; | ||
|
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. キューとdepthをpairでまとめる書き方もあります。 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. 変数名のみから中身が想像できるのが好みですが,これくらいのコードなら問題ないとも思います. |
||
| q.push(root); | ||
|
|
||
| int depth = 0; | ||
|
|
||
| while (!q.empty()) { | ||
| int level_size = q.size(); | ||
| ++depth; | ||
|
|
||
| for (int i = 0; i < level_size; ++i) { | ||
|
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. 現在のレベルのサイズを固定してそこまで回す方法も良いですが、別々のキューを使う方法の方が可読性に優れると感じます。 while (!q.empty()) {
std::queue<TreeNode*> next_q;
++depth;
while (!q.empty()) {
TreeNode* node = q.front();
q.pop();
if (node->left != nullptr) {
next_q.push(node->left);
}
if (node->right != nullptr) {
next_q.push(node->right);
}
}
q = std::move(next_q);
}
https://discord.com/channels/1084280443945353267/1201211204547383386/1219179255615717399 |
||
| TreeNode* node = q.front(); | ||
| q.pop(); | ||
| if (node->left != nullptr) { | ||
| q.push(node->left); | ||
| } | ||
|
Comment on lines
+128
to
+132
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. NULLチェックですが、push前にやる方法のほか、pop直後にやる方法もあります。 |
||
| if (node->right != nullptr) { | ||
| q.push(node->right); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return depth; | ||
Apo-Matchbox marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| }; | ||
|
|
||
| ``` | ||
|
|
||
| - トータルで1Qにかかる時間が短くなってきた。 | ||
|
|
||
| ## Step3 *自然な流れ(感覚に落とし込む) | ||
| 1. 2 min | ||
| 2. 2 min | ||
| 2. 1min | ||
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.
docto-rinさんが言及されていた「Nullチェックをpop直後に行う」スタイルをとるとこの例外処理は省略可能ですね.