Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 165 additions & 0 deletions 111. Minimum Depth of Binary Tree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# step 1

したから積み上げる再帰DFS
```python
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if root is None:
return 0

if root.left is not None and root.right is not None:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is not Noneという条件、なくても問題なさそうに見えます。

Copy link

@colorbox colorbox Feb 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

すいません、間違えました、これは必要ですね。
訂正箇所を間違えました

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is not Noneに関しては、なくても動きますが、google style guideに以下のようにあり、それを参考にしてます

Always use if foo is None: (or is not None) to check for a None value. E.g., when testing whether a variable or argument that defaults to None was set to some other value. The other value might be a value that’s false in a boolean context!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

L10-L11 は L12-L14 と処理が被っているので、L12-L14を修正することでなくせそうです。

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

すいません、間違えました。
これをやろうとすると、rootがNoneのときの処理が面倒になるので、ここはこのままで良さそうです

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

無理やりやろうとすると、L10-L16をしたみたいに書き換える感じですかね

max_num_of_nodes = 10 ** 5
left_depth = max_num_of_nodes
if root.left is not None:
    left_depth = self.minDepth(root.left)
right_depth = max_num_of_nodes
if root.right is not None:
    right_depth = self.minDepth(root.right)
return min(left_depth, right_depth) + 1

return min(self.minDepth(root.left), self.minDepth(root.right)) + 1
if root.left is not None:
return self.minDepth(root.left) + 1
if root.right is not None:
return self.minDepth(root.right) + 1
return 1
```

list二つで行う階層型BFS

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好みかもですが、私もBFSは、レベル別で管理した2つのリストでやる派です。

```python
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if root is None:
return 0
nodes_in_depth = [root]
depth = 1
while nodes_in_depth:
nodes_in_next_depth = []
for node in nodes_in_depth:
if node.left is None and node.right is None:
return depth
if node.left is not None:
nodes_in_next_depth.append(node.left)
if node.right is not None:
nodes_in_next_depth.append(node.right)
nodes_in_depth = nodes_in_next_depth
depth += 1
```

dequeを使ったBFS
```python
from collections import deque


class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if root is None:
return 0
nodes_and_depths = deque([(root, 1)])
while nodes_and_depths:
node, depth = nodes_and_depths.popleft()
if node.left is None and node.right is None:
return depth
if node.left is not None:
nodes_and_depths.append((node.left, depth + 1))
if node.right is not None:
nodes_and_depths.append((node.right, depth + 1))
```

配るタイプの再帰DFS
```python
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if root is None:
return 0

max_num_of_nodes = 10 ** 5
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

自分はinfを使いたくなるのですが、infはfloat型なので抵抗がある方もいらっしゃるようです
fhiyo/leetcode#41 (comment)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

マジックナンバーは避けたいという気持ちもあります。
INT_MAX とかのほうが気分がいいですね。
https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.43n5ir9lkgax

min_depth = max_num_of_nodes
def min_depth_helper(node: Optional[TreeNode], depth: int) -> None:
nonlocal min_depth
if node.left is None and node.right is None:
min_depth = min(min_depth, depth)
return
if node.left is not None:
min_depth_helper(node.left, depth + 1)
if node.right is not None:
min_depth_helper(node.right, depth + 1)
min_depth_helper(root, 1)
return min_depth
```

# step 2
- https://github.com/colorbox/leetcode/pull/36/files
- BFS、rootのNoneチェックをせずに進めて、最後にreturn 0している。
- 必ず返り値があるのが一目でわかる。
- 先にreturnする方が考えることが少なそうではある
- https://github.com/tarinaihitori/leetcode/pull/22/files#r1904986676
- > queue の中身のデータの整合性が取れているということは、
読んでいる人からすると全部読み終わらないと分からないからです。書いている人は分かるわけですが。
つまり、一つの変数に、2つの違う種類のものを入れておいて、その境界を個数で管理しているわけですよね。

maximum depth of binary treeとあまり変わらない。前回は、leftじゃないノードでも
返り値の更新を逐一して、全てのノードを調べたら求めたい値が出たのに対し、今回は、ちゃんとleftかどうかを
確認する必要があった。

```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 not None and root.right is not None:
return 1 + min(self.minDepth(root.left), self.minDepth(root.right))
if root.left is not None:
return 1 + self.minDepth(root.left)
else:
return 1 + self.minDepth(root.right)
```
leafかどうかが最初に気になったのでそこからreturnするようにした。
最後のelseは、1.決して字下げする、2.`if root.right is not None`とするなどできる。

- leaf nodeである -> 1を返す
- 子を両方とも持つ -> 再帰
- 片側だけ子を持つ
- 左だけ -> 左だけ再帰
- 右だけ -> 右だけ再帰
みたいなことを考えており、対称っぽくなればと思いこの形にしている。

```python
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if root is None:
return 0

nodes_in_depth = [root]
depth = 1
while nodes_in_depth:
nodes_in_next_depth = []
for node in nodes_in_depth:
if node.left is None and node.right is None:
return depth

if node.left is not None:
nodes_in_next_depth.append(node.left)
if node.right is not None:
nodes_in_next_depth.append(node.right)
nodes_in_depth = nodes_in_next_depth
depth += 1
```

# step 3

```python
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if root is None:
return 0

nodes_in_depth = [root]
depth = 1
while nodes_in_depth:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここ、True にしてもいいと思います。抜けることはないので。

nodes_in_next_depth = []
for node in nodes_in_depth:
if node.left is None and node.right is None:
return depth

if node.left is not None:
nodes_in_next_depth.append(node.left)
if node.right is not None:
nodes_in_next_depth.append(node.right)
nodes_in_depth = nodes_in_next_depth
depth += 1
```