-
Notifications
You must be signed in to change notification settings - Fork 0
111. Minimum Depth of Binary Tree #16
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,139 @@ | ||
| # 111. Minimum Depth of Binary Tree | ||
| * 問題: https://leetcode.com/problems/minimum-depth-of-binary-tree/ | ||
| * 言語: Python | ||
|
|
||
| ## Step1 | ||
| * 木構造の最小の高さを求める | ||
| * 深さ優先探索(DFS)だとすべてのノードを訪れる必要があるので幅優先探索(BFS)でノードを訪れていき、葉ノードを見つけたらその時点の深さを返し早期終了する方針 | ||
|
|
||
| ### すべてのテストケースを通過しないコード | ||
| ```py | ||
| class Solution: | ||
| def minDepth(self, root: Optional[TreeNode]) -> int: | ||
| if not root: | ||
| return 0 | ||
|
|
||
| visited_node = deque([root]) | ||
| min_tree_depth = 1 | ||
|
|
||
| while visited_node: | ||
| node = visited_node.popleft() | ||
| if node.left and node.right: | ||
| min_tree_depth += 1 | ||
| if not node.left and not node.right: | ||
|
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. None であるかどうかをチェックする場合、 参考までにスタイルガイドへのリンクを貼ります。 https://google.github.io/styleguide/pyguide.html#2144-decision 上記のスタイルガイドは唯一絶対のルールではなく、複数あるスタイルガイドの一つに過ぎないということを念頭に置くことをお勧めします。また、所属するチームにより何が良いとされているかは変わります。自分の中で良い書き方の基準を持ちつつ、チームの平均的な書き方で書くことをお勧めいたします。 |
||
| return min_tree_depth | ||
| if node.left: | ||
| visited_node.append(node.left) | ||
| if node.right: | ||
| visited_node.append(node.right) | ||
| ``` | ||
|
|
||
| * 最初の15分は入力を配列と勘違いしていた | ||
| * 子ノードを2つ持つノードが左側に存在すると余計に1つカウントする | ||
| * 1時間ほど経過していたので正答を見る | ||
|
|
||
| ### 正答 | ||
| ```py | ||
| class Solution: | ||
| def minDepth(self, root: Optional[TreeNode]) -> int: | ||
| if not root: | ||
| return 0 | ||
|
|
||
| node_and_depth = deque([(root, 1)]) | ||
|
|
||
| while node_and_depth: | ||
| node, depth = node_and_depth.popleft() | ||
| if not node.left and not node.right: | ||
| return depth | ||
| if node.left: | ||
| node_and_depth.append((node.left, depth + 1)) | ||
| if node.right: | ||
| node_and_depth.append((node.right, depth + 1)) | ||
| ``` | ||
| * 考え方はだいたい同じだが、木の深さをレベルごとに保持するためにキューにノードとそのレベルでの深さのタプルを格納 | ||
|
|
||
| ## Step2 | ||
| * 典型コメント: https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.prowafrzksyh | ||
| * https://github.com/sakupan102/arai60-practice/pull/23 | ||
| - Python | ||
| - 同じBFSだが、2つのlistを使った方法 | ||
| * https://github.com/Yoshiki-Iwasa/Arai60/pull/25 | ||
| - Rust | ||
| - キューによるBFS、再帰によるDFS | ||
| - 以下のように、左右の子ノードの処理をまとめているのが印象的 | ||
| ```rust | ||
| for child in [node_ref.left.as_ref(), node_ref.right.as_ref()] { | ||
| if let Some(child_node) = child { | ||
| queue.push_back((Rc::clone(child_node), depth + 1)); | ||
| } | ||
| } | ||
| ``` | ||
| * https://github.com/olsen-blue/Arai60/pull/22 | ||
| - Python | ||
| - > あー、この問題が、たとえば4分木だったら、全部の組み合わせ16通りを全部書き出しますか、という気持ちですね。 | ||
|
|
||
| ### 別解(読みやすく書き直す) | ||
| #### 再帰DFSによる方法 | ||
| ```py | ||
| class Solution: | ||
| def minDepth(self, root: Optional[TreeNode]) -> int: | ||
| if not root: | ||
| return 0 | ||
|
|
||
| if not root.left and not root.right: | ||
|
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. この行でreturn 1をするのではなく、最後に左右のサブツリーの小さい方+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. その場合87と89の条件をそれぞれ否定に変えてleftがnoneなら右側のサブツリーの深さ+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. 以下のような感じですかね。(だいぶ変わってしまいましたが) class Solution:
def minDepth(self, root: Optional[TreeNode]) -> int:
if root is None:
return 0
left_depth = self.minDepth(root.left)
right_depth = self.minDepth(root.right)
if left_depth == 0 or right_depth == 0:
return max(left_depth, right_depth) + 1
return min(left_depth, right_depth) + 1 |
||
| return 1 | ||
|
|
||
| min_depth = float("inf") | ||
| if root.left: | ||
| min_depth = min(min_depth, self.minDepth(root.left) + 1) | ||
| if root.right: | ||
| min_depth = min(min_depth, self.minDepth(root.right) + 1) | ||
|
|
||
| return min_depth | ||
| ``` | ||
| * 時間計算量: $O(n)$ | ||
|
|
||
| #### スタックDFSによる方法 | ||
| ```py | ||
| class Solution: | ||
| def minDepth(self, root: Optional[TreeNode]) -> int: | ||
| if not root: | ||
| return 0 | ||
|
|
||
| node_and_depth = [(root, 1)] | ||
| min_depth = float("inf") | ||
| while node_and_depth: | ||
| node, depth = node_and_depth.pop() | ||
| if not node.left and not node.right: | ||
| min_depth = min(min_depth, depth) | ||
| if node.left: | ||
| node_and_depth.append((node.left, depth + 1)) | ||
| if node.right: | ||
| node_and_depth.append((node.right, depth + 1)) | ||
|
|
||
| return min_depth | ||
| ``` | ||
| * 時間計算量: $O(n)$ | ||
|
|
||
| # Step3 | ||
| * BFSによる方法 | ||
| ```py | ||
| class Solution: | ||
| def minDepth(self, root: Optional[TreeNode]) -> int: | ||
| if not root: | ||
| return 0 | ||
|
|
||
| node_and_depth = deque([(root, 1)]) | ||
| while node_and_depth: | ||
| node, depth = node_and_depth.popleft() | ||
| if not node.left and not node.right: | ||
| return depth | ||
| if node.left: | ||
| node_and_depth.append((node.left, depth + 1)) | ||
| if node.right: | ||
| node_and_depth.append((node.right, depth + 1)) | ||
| ``` | ||
| * 解答時間: | ||
| - 1回目: 1:50 | ||
| - 2回目: 1:57 | ||
| - 3回目: 1:55 | ||
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.
visitedに対しての使い方がイメージに合わないなと思いました。
nodeと深さを格納しているnode_and_depthは分かりやすいと感じました。