diff --git "a/\347\253\266\346\212\200\343\203\227\343\203\255\345\260\261\346\264\273\351\203\250PR\347\224\250/111. Minimum Depth of Binary Tree.md" "b/\347\253\266\346\212\200\343\203\227\343\203\255\345\260\261\346\264\273\351\203\250PR\347\224\250/111. Minimum Depth of Binary Tree.md" new file mode 100644 index 0000000..80b383c --- /dev/null +++ "b/\347\253\266\346\212\200\343\203\227\343\203\255\345\260\261\346\264\273\351\203\250PR\347\224\250/111. Minimum Depth of Binary Tree.md" @@ -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') + 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: + 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 + 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 +```