-
Notifications
You must be signed in to change notification settings - Fork 0
104. Maximum Depth of Binary Tree #4
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: master
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,156 @@ | ||
| <問題> | ||
| https://leetcode.com/problems/maximum-depth-of-binary-tree/ | ||
|
|
||
| # step1 | ||
|
|
||
| 5分程度答えを見ずに考えて、手が止まるまでやってみる。 | ||
| 何も思いつかなければ、答えを見て解く。 | ||
| ただし、コードを書くときは答えを見ないこと。 | ||
| 正解したら一旦OK。 | ||
| 思考過程もメモしてみる。 | ||
|
|
||
| ```c++ | ||
| class Solution { | ||
| public: | ||
| int maxDepth(TreeNode* root) { | ||
| TreeNode* current_node; | ||
| TreeNode* left_node; | ||
| TreeNode* right_node; | ||
| map<TreeNode*, int> height; | ||
|
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. Hashmapを使うという視点はなかったので、新鮮でした。 |
||
| queue<TreeNode*> node_to_visit; | ||
|
|
||
| current_node=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. 代入演算子の両側にはスペースを 1 つずつ空けることをおすすめいたします。 https://google.github.io/styleguide/cppguide.html#Horizontal_Whitespace
|
||
| height[current_node] = 1; | ||
| node_to_visit.push(current_node); | ||
|
|
||
| while (current_node != nullptr && !node_to_visit.empty()) { | ||
|
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. 非 nullptr のポインターは、条件式として見たときに真となるため、個人的には
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. ありがとうございます。 |
||
| current_node = node_to_visit.front(); | ||
| if (current_node->left != nullptr) { | ||
| left_node = current_node->left; | ||
| node_to_visit.push(left_node); | ||
| height[left_node] = height[current_node] + 1; | ||
| } | ||
| if (current_node->right != nullptr) { | ||
| right_node = current_node->right; | ||
| node_to_visit.push(right_node); | ||
| height[right_node] = height[current_node] + 1; | ||
| } | ||
| node_to_visit.pop(); | ||
| } | ||
| return height.rbegin()->second; | ||
| } | ||
| }; | ||
| ``` | ||
|
|
||
| 【考えたこと】 | ||
|
|
||
| - 幅優先探索、深さ優先探索で解けそう。 | ||
| - 木を辿っていく際に、自分の高さを保管しておく。 | ||
|
|
||
| 次に辿った高さ=今の高さ+1 | ||
|
|
||
| - mapのキーとして、ノードのアドレスを指定するのは自然なのか。 | ||
| - コードを書く中で存在しないアドレスに何度もアクセスして苦労した。 | ||
|
|
||
| # step2 | ||
| 他の方が描いたコードを見て、参考にしてコードを書き直してみる。 | ||
| 参考にしたコードのリンクは貼っておく。 | ||
| 読みやすいことを意識する。 | ||
| 他の解法も考えみる。 | ||
| 計算量:O(N) N:ノード数 | ||
|
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. 時間と空間のどちらの計算量か明示すると良いと思います。
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. ありがとうございます。 |
||
|
|
||
|
|
||
| ```c++ | ||
| class Solution { | ||
| public: | ||
| int maxDepth(TreeNode* root) { | ||
| TreeNode* current_node; | ||
| map<TreeNode*, int> height; | ||
| queue<TreeNode*> node_to_visit; | ||
| if (root == nullptr){ | ||
| return 0; | ||
| } | ||
|
Comment on lines
+70
to
+72
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. 私の趣味としては、これを一番上に持っていきます。 |
||
| current_node = root; | ||
| node_to_visit.push(current_node); | ||
| height[current_node] = 1; | ||
| max_depth=0; | ||
|
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. height と depth を同じ意味で使っているように見えます。どちらかに統一したほうがシンプルになると思います。 |
||
| while (!node_to_visit.empty()) { | ||
| current_node = node_to_visit.front(); | ||
| node_to_visit.pop(); | ||
| max_depth = max(max_depth, height[current_node]) | ||
| if (current_node->left != nullptr) { | ||
| node_to_visit.push(current_node->left); | ||
| height[current_node->left] = height[current_node] + 1; | ||
| } | ||
| if (current_node->right != nullptr) { | ||
| node_to_visit.push(current_node->right); | ||
| height[current_node->right] = height[current_node] + 1; | ||
| } | ||
| } | ||
| return max_depth; | ||
| } | ||
| }; | ||
| ``` | ||
|
|
||
| - 空の配列を渡された時にも対応できるように修正 | ||
| - TreeNodeの変数でleft_nodeとright_nodeに分けていただが、変数までは作る必要がないかと判断。 | ||
| - スペースを修正しました。 | ||
| - frontとpopはなるべく近づけました | ||
| - 上記解き方は、幅優先探索。 | ||
| - step1でのrbegin()では必ずしも最大深さにはならないので、たどるノードの最大値を出すように修正 | ||
|
|
||
| - pairはあまり使わないほうが良い | ||
| https://github.com/rossy0213/leetcode/pull/10#discussion_r1564630314 | ||
|
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. 私はそこまでうるさくなくていいかなという気持ちです。 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. 私は Java の Readablity Review で指摘されて、トラウマになっているため、やや過敏に反応してしまっています。 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. まあ、社内ではないので、そういう文化圏もあります、くらいでいいように思います。 |
||
|
|
||
| - 深さ優先探索ならstackで深さとノードを保持して、その都度今までの最大深さと今の深さを比較して、深さの最大値を更新していけば良い。 | ||
| https://github.com/Mike0121/LeetCode/pull/6/files | ||
|
|
||
| - 同じ高さのノードをwhileの中で全て調べ切れば、各ノードの深さをずっと覚えておく必要はない。 | ||
|
|
||
| - もちろん再帰でも書ける。 | ||
|
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. 実際に実装されてみると良いと思いました。
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. ありがとうございます! |
||
|
|
||
| 参考:https://github.com/hayashi-ay/leetcode/pull/22 | ||
|
|
||
| - 幅優先探索でdequeに、ノードと高さを組みで取り出しと入れていく。 | ||
|
|
||
| https://github.com/fhiyo/leetcode/pull/23#discussion_r1675990961 | ||
|
|
||
|
|
||
| # step3 | ||
|
|
||
| 今度は、時間を測りながら、もう一回、書きましょう。書いてアクセプトされたら文字消してもう一回書く。これを10分以内に一回もエラーを出さずに書ける状態になるまで続ける。3回続けてそれができたらその問題はOK。 | ||
|
|
||
| 実施しました。 | ||
|
|
||
|
|
||
| ```c++ | ||
| class Solution { | ||
| public: | ||
| int maxDepth(TreeNode* root) { | ||
| TreeNode* current_node; | ||
|
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. 個人的には、current_ がほとんど情報持っていないので、単に node でも読みやすさとしてはあまり変わらない、と思います。
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. ありがとうございます。 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. そうですね。役割がなにか次第でもあります。 |
||
| map<TreeNode*, int> height; | ||
| queue<TreeNode*> node_to_visit; | ||
| if (root == nullptr){ | ||
| return 0; | ||
| } | ||
| current_node = root; | ||
| node_to_visit.push(current_node); | ||
| height[current_node] = 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.
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. 1段ずつ下がっていく度にdepthを更新する方法もあるかもしれません。 pythonで恐縮ですが、ご参考。 from collections import deque
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def maxDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
candidates = deque([(root)])
depth = 0
while candidates:
depth += 1
for _ in range(len(candidates)):
node = candidates.popleft()
if node.left:
candidates.append(node.left)
if node.right:
candidates.append(node.right)
return depthThere 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. https://discord.com/channels/1084280443945353267/1303605021597761649/1306631474065309728
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. すみません。 |
||
| max_depth=0; | ||
| while (!node_to_visit.empty()) { | ||
| current_node = node_to_visit.front(); | ||
| node_to_visit.pop(); | ||
| max_depth = max(max_depth, height[current_node]) | ||
| if (current_node->left != nullptr) { | ||
| node_to_visit.push(current_node->left); | ||
| height[current_node->left] = height[current_node] + 1; | ||
| } | ||
| if (current_node->right != nullptr) { | ||
| node_to_visit.push(current_node->right); | ||
| height[current_node->right] = height[current_node] + 1; | ||
| } | ||
| } | ||
| return max_depth; | ||
| } | ||
| }; | ||
| ``` | ||
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.
変数を作るのはいいんですが、スコープが広すぎるでしょう。
まず、初期化されていないので、読んだら未定義動作であることを警戒します。
そして、それが実際には使われている範囲が3行ずつなのだけれども、広いスコープにあるということはスコープを抜けても忘れてはいけないやつなのだろうと思い下の方まで保持し続けます。
ちなみに、古い C の流儀で、変数は上の方にまとめて宣言というのはありますが、現代的ではないかと思います。
current_node も
TreeNode* current_node = 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.
ありがとうございます。
変数が定義されてから、すぐに変数が出てきたほうが変数を覚えておく必要がなくなり読みやすくなると理解しました。