Skip to content
Merged
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
132 changes: 132 additions & 0 deletions 競技プロ就活部PR用/111. Minimum Depth of Binary Tree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@

## BFS
時間計算量: O(N)
空間計算量: O(N)

---
### 1回目 (2m55s)
手で行う時をイメージし、すんなり解くことができた。

```python
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
min_leaf_depth = float('inf')
Copy link
Copy Markdown

@sakupan102 sakupan102 May 9, 2024

Choose a reason for hiding this comment

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

これ不要かと思います
2ndのコメントにありましたね

next_nodes = deque([(root, 1)])

while next_nodes:
node, depth = next_nodes.popleft()

if not node.left and not node.right:
return depth

if node.left: next_nodes.append((node.left, depth + 1))
if node.right: next_nodes.append((node.right, depth + 1))
```


### 2回目
BFSで解けば、子ノードがなくなった時点でそこが最も浅い葉ノードなので、
min_depthを作成する必要がないことに気がつく。
```python
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
next_nodes = deque([(root, 1)])

while next_nodes:
node, depth = next_nodes.popleft()
if not node.left and not node.right:
return depth

if node.left: next_nodes.append((node.left, depth + 1))
if node.right: next_nodes.append((node.right, depth + 1))

```

### 3回目
next_nodesに入るのは、nodeだけでなくdepthとのペアのため、命名を変更。
```python
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
nodes_with_depth = deque([(root, 1)])

while nodes_with_depth:
node, depth = nodes_with_depth.popleft()
if not node.left and not node.right:
return depth

if node.left: nodes_with_depth.append((node.left, depth + 1))
if node.right: nodes_with_depth.append((node.right, depth + 1))
```


## DFS
時間計算量: O(N)
空間計算量: O(N)

---
### 1回目
外部の変数を参照・更新するためnonlocalを指定したが、少し読みづらい。
```python
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0
min_depth = float('inf')

def minDepth_helper(node, depth):
nonlocal min_depth
if not node:
return depth

if not node.left and not node.right:
min_depth = min(min_depth, depth)

left_depth = minDepth_helper(node.left, depth + 1)
right_depth = minDepth_helper(node.right, depth + 1)

minDepth_helper(root, 1)
return min_depth
```

### 2回目 nonlocalを使わない方法
```python
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if not root:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

この条件がTrueになるのは与えられたTreeがNoneの場合だけですよね。
個人的にはNoneの場合の処理は再帰の外に出しちゃって、再帰の引数にはNoneが含まれないようにしてもよいかと思いました。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

ありがとうございます。内部に再帰用のhelper関数を作成して、if not rootはその外側というイメージであっていますか?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

そんな感じですね

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

ありがとうございます。特に引数を増やす必要がなければ、再帰用に関数を作成しない方が良いと勝手に思っていました。

return 0
if not root.left and not root.right:
return 1
min_depth = float('inf')
if root.left: min_depth = min(min_depth, self.minDepth(root.left))
if root.right: min_depth = min(min_depth, self.minDepth(root.right))

return min_depth + 1
```

### 追記 stackを利用した解法
```python
class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if not root:
return 0

min_depth = float('inf')
nodes_and_depth = [(root, 1)]

while nodes_and_depth:
node, depth = nodes_and_depth.pop()
if not node.left and not node.right:
min_depth = min(depth, min_depth)
if depth >= min_depth: # 枝刈り(depthがmin_depth以上の場合それ以降の探索を打ち切る)を追加
continue
Comment on lines +124 to +127
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

このif文逆にしてもいいですね。

if node.right: nodes_and_depth.append([node.right, depth + 1])
if node.left: nodes_and_depth.append([node.left, depth + 1])

return min_depth
```