-
Notifications
You must be signed in to change notification settings - Fork 0
111. Minimum Depth of Binary Tree #22
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,72 @@ | ||
| # 111. Minimum Depth of Binary Tree | ||
|
|
||
| https://leetcode.com/problems/minimum-depth-of-binary-tree/description/ | ||
|
|
||
| ## step1(まず通す) | ||
|
|
||
| https://leetcode.com/problems/maximum-depth-of-binary-tree/description/ とほぼ同じ。 | ||
|
|
||
| 違う点は、一番深いところは全ノード見ないとがわからないが、一番浅いところは同じ高さごとに見ていって、最初に見つかった葉のところなのでそれ以降を見なくて済む。 | ||
|
|
||
| 再帰で自然に書くと全部見ることになる。 | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def minDepth(self, root: Optional[TreeNode]) -> int: | ||
| if root is None: | ||
| return 0 | ||
| if root.left is None and root.right is None: | ||
| return 1 | ||
| if root.left is None: | ||
| return self.minDepth(root.right) + 1 | ||
| if root.right is None: | ||
| return self.minDepth(root.left) + 1 | ||
| return min(self.minDepth(root.left), self.minDepth(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. 改行があったほうが見やすいかなと思いました。 def minDepth(self, root: Optional[TreeNode]) -> int:
if root is None:
return 0
if root.left is None and root.right is None:
return 1
if root.left is None:
return self.minDepth(root.right) + 1
if root.right is None:
return self.minDepth(root.left) + 1
return min(self.minDepth(root.left), self.minDepth(root.right)) + 1
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. ありがとうございます。今回は確かにそうかもしれませんね。 |
||
| ``` | ||
|
|
||
| 例えば、 | ||
|
|
||
| ```txt | ||
| 0 | ||
| / \ | ||
| 1 2 | ||
| /\ | ||
| ...(めっちゃ深い) | ||
| ``` | ||
|
|
||
| みたいな時にはだいぶ計算量が違う。 | ||
|
|
||
| 逆に、root から唯一の葉まで一本道みたいなときは見るノード数が同じになる。 | ||
|
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. どの葉も同じ深さにあるようなときも見るノード数は同じですね。 |
||
|
|
||
| ## step2(整形&他の人のコードを読む) | ||
|
|
||
| 2点知りたいことがある | ||
|
|
||
| - [昨日のやつにいただいたコメント](https://github.com/MA-yo-TA/leetcode/pull/21#discussion_r3506905860) に関連して、next_layer の初期化は while の冒頭と nodes とセットでやるのとみなさんどちらで書いているのか | ||
| - https://github.com/shintaro1993/arai60/pull/26/changes | ||
| - この方は while の冒頭 | ||
| - ついでに depth の更新は while の最後 | ||
| - 自分としては「nodes があるなら一段加算」という気がするので while の判定の直後に書きたい気がしているが変な気もする | ||
| - while ループを return 以外で抜けることはないが、それを型チェッカーに示す方法としては何がいいのか。 | ||
| - 関数の末尾でエラーを出す? | ||
| - raise RuntimeError("unreachable") しているもの | ||
| - https://github.com/tom4649/Coding/pull/20/changes#diff-974436ac64380be2414ffa842d4dc5dd641279483233dca84985f0deee4311e2R24 | ||
| - | ||
|
|
||
| - https://github.com/tom4649/Coding/pull/20/changes#r2939305873 | ||
| - min_depth の初期値を float("inf") としていて、「ここの初期値はどんな感じで決められましたか?」「intのinfがないので、floatのinfで代用しました(質問の意図に合っているか分かりませんが)」とあるが、「(int からキャストできる float における)min() の単位元だから」というのが意図に沿った回答だろうか? | ||
| - 単位元 `e` は、(Python 風にいうと)同じ型のオブジェクト `x` とその型の引数を二つ取る関数・メソッド・演算子 `f` に対して常に(どんな `x` でも) `f(e, x) = x` となるもの | ||
| - counter を += で増やしていくなら 0 | ||
| - min なら float("inf")(か、絶対越えられない適当なデカい値) | ||
| - max なら float("-inf") か 0(対象が自然数の場合) | ||
| - メリットは初回の操作がおかしくならないので初回と2回目以降を同じように扱えること | ||
| - 自分にも「ある変数を2項演算によって更新していくとき、初期値はその演算の単位元であるのが好ましい」という感覚がある | ||
| - ただし、操作が行われなかったときに初期値をそのまま返すような場合は気をつけた方がいい。期待されている出力が異なることがあるので。 | ||
| - https://github.com/garunitule/coding_practice/blob/main/Tree/111/memo.md | ||
| - ここにも初期値をどうするかの議論がある | ||
| - 2 << 30 や 1 << 30 が「絶対越えられない適当なデカい数」として上がっている | ||
|
|
||
| ## step3(10分以内にさっとかける \* 3回) | ||
|
|
||
| 結局ループでは最初から次のレイヤーを探しに行きたい気がして諸々の更新処理は全部最後にした。仕事の引き継ぎだとすると、朝来て「細かいところは昨日のやつ全部やっといてくれよ」と思いそう。 | ||
|
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. https://github.com/MA-yo-TA/leetcode/pull/21/changes#r3512713879 上記のやり方も許容される範囲に入っています。
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. ありがとうございます。いろいろな書き方を読めるようになるためにも今後も他の方のコードをいろいろ読もうと思います。 加えて、前回と今回レビューいただいて、自分の好みを持つ(知る)ためには色々考えながら複数パターンをある程度の量書くことが必要だなと感じたのでそのへんもこの練習会で意識して取り組みます。 |
||
| あとループの前に登場人物が全員見えてた方が落ち着く。 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| from typing import Optional | ||
|
|
||
|
|
||
| class TreeNode: | ||
| def __init__(self, val=0, left=None, right=None): | ||
| self.val = val | ||
| self.left = left | ||
| self.right = right | ||
|
|
||
|
|
||
| class Solution: | ||
| def minDepth(self, root: Optional[TreeNode]) -> int: | ||
| if root is None: | ||
| return 0 | ||
|
|
||
| depth = 0 | ||
| nodes = [root] | ||
| while nodes: | ||
| next_layer = [] | ||
| depth += 1 | ||
| for node in nodes: | ||
| if node.left is None and node.right is None: | ||
| return depth | ||
| if node.left is not None: | ||
| next_layer.append(node.left) | ||
| if node.right is not None: | ||
| next_layer.append(node.right) | ||
| nodes = next_layer |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| from typing import Optional | ||
|
|
||
|
|
||
| class TreeNode: | ||
| def __init__(self, val=0, left=None, right=None): | ||
| self.val = val | ||
| self.left = left | ||
| self.right = right | ||
|
|
||
|
|
||
| class Solution: | ||
| def minDepth(self, root: Optional[TreeNode]) -> int: | ||
| if root is None: | ||
| return 0 | ||
|
|
||
| nodes = [root] | ||
| depth = 0 | ||
| while nodes: | ||
| next_layer = [] | ||
| depth += 1 | ||
| for node in nodes: | ||
| if node.left is None and node.right is None: | ||
| return depth | ||
| if node.left is not None: | ||
| next_layer.append(node.left) | ||
| if node.right is not None: | ||
| next_layer.append(node.right) | ||
| nodes = next_layer | ||
|
|
||
| raise RuntimeError("unreachable") |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| from typing import Optional | ||
|
|
||
|
|
||
| class TreeNode: | ||
| def __init__(self, val=0, left=None, right=None): | ||
| self.val = val | ||
| self.left = left | ||
| self.right = right | ||
|
|
||
|
|
||
| class Solution: | ||
| def minDepth(self, root: Optional[TreeNode]) -> int: | ||
| if root is None: | ||
| return 0 | ||
|
|
||
| nodes = [root] | ||
| next_layer = [] | ||
| depth = 1 | ||
| while nodes: | ||
| for node in nodes: | ||
| if node.left is None and node.right is None: | ||
| return depth | ||
| if node.left is not None: | ||
| next_layer.append(node.left) | ||
| if node.right is not None: | ||
| next_layer.append(node.right) | ||
| nodes = next_layer | ||
| next_layer = [] | ||
| depth += 1 | ||
|
|
||
| raise RuntimeError("unreachable") |
Uh oh!
There was an error while loading. Please reload this page.
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.
一応ですが、再帰というより、深さ優先探索を再帰でやると、ですね。
(私はこういう書き方はあまりしませんが、) 幅優先探索を再帰で書くことですべてを探索しないようにすることはできます。
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.
ありがとうございます。そうですね、自分の中で明示的な区別ができてなくて自然にという言葉で流してしまってましたが、本来は再帰で書くことと深さ優先探索をすることは別のことですよね。
指摘してくださってありがとうございます。好みでなくてもそういう書き方ができるということ自体は考慮に入れた上で選べるようにします。