-
Notifications
You must be signed in to change notification settings - Fork 0
102. Binary Tree Level Order Traversal #28
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,140 @@ | ||
# 102. Binary Tree Level Order Traversal | ||
|
||
## 1st | ||
|
||
### ① | ||
|
||
幅優先探索で左から右に順々に処理すればよい。 | ||
append_if_existsはあっても無くてもいいと思う。 | ||
キューはレベルごとに用意しているが、同じキューに入れてループを回すタイミングで入っているノードの数分だけ処理をする、を繰り返しても良い。 | ||
今回はdequeを使ったけどlistでも良い。内側の `while nodes` が `for node in nodes` になる | ||
level_order_valuesは `list[list[int]]`, current_level_valuesは `list[int]` になっていて少し分かりづらいだろうか。 | ||
valuesはcurrent_level_と接頭辞があるので、合わせてnodesの方もcurrent_level_nodesとした方が今回は良かったかもしれない。 | ||
|
||
|
||
所要時間: 9:01 | ||
|
||
n: ノード数 | ||
- 時間計算量: O(n) | ||
- 空間計算量: O(n) | ||
|
||
```py | ||
# Definition for a binary tree node. | ||
# class TreeNode: | ||
# def __init__(self, val=0, left=None, right=None): | ||
# self.val = val | ||
# self.left = left | ||
# self.right = right | ||
class Solution: | ||
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: | ||
def append_if_exists(nodes: deque[TreeNode], node: Optional[TreeNode]): | ||
if node: | ||
nodes.append(node) | ||
|
||
if not root: | ||
return [] | ||
level_order_values = [] | ||
nodes = deque([root]) | ||
while nodes: | ||
next_level_nodes = deque([]) | ||
current_level_values = [] | ||
while nodes: | ||
node = nodes.popleft() | ||
current_level_values.append(node.val) | ||
append_if_exists(next_level_nodes, node.left) | ||
append_if_exists(next_level_nodes, node.right) | ||
nodes = next_level_nodes | ||
level_order_values.append(current_level_values) | ||
return level_order_values | ||
``` | ||
|
||
### ② | ||
|
||
再帰。最悪2000回スタックに積まれるので環境によってはRecursionError。 | ||
変数名が全体的に長いのでゴチャ付いてる感じがある。やっぱりcurrent_level_の接頭辞は無くてもいいか? | ||
|
||
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. currentに関して、自分のPRで以前コメントをいただいたのでリンク貼っておきます。 |
||
所要時間: 5:32 | ||
|
||
n: ノード数 | ||
- 時間計算量: O(n) | ||
- 空間計算量: O(n) | ||
|
||
```py | ||
class Solution: | ||
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: | ||
def level_order_helper(current_level_nodes: list[TreeNode], level_order_values: list[list[int]]) -> list[list[int]]: | ||
if not current_level_nodes: | ||
return level_order_values | ||
current_level_values = [] | ||
next_level_nodes = [] | ||
for node in current_level_nodes: | ||
current_level_values.append(node.val) | ||
if node.left: | ||
next_level_nodes.append(node.left) | ||
if node.right: | ||
next_level_nodes.append(node.right) | ||
level_order_values.append(current_level_values) | ||
return level_order_helper(next_level_nodes, level_order_values) | ||
|
||
if not root: | ||
return [] | ||
return level_order_helper([root], []) | ||
``` | ||
|
||
## 2nd | ||
|
||
### 参考 | ||
|
||
- https://discord.com/channels/1084280443945353267/1227073733844406343/1238016881412149249 | ||
- https://discord.com/channels/1084280443945353267/1196472827457589338/1235538738927370322 | ||
- https://discord.com/channels/1084280443945353267/1201211204547383386/1218448578767491152 | ||
- https://discord.com/channels/1084280443945353267/1201211204547383386/1218244966946701363 | ||
- https://discord.com/channels/1084280443945353267/1200089668901937312/1211206574022991882 | ||
|
||
|
||
あえてこちらで実装するのはそんなにしなさそうだが、深さ優先探索で書いてみる。 | ||
`while depth >= len(level_order_values)` は | ||
`if depth == len(level_order_values): # depth <= len(level_order_values)` みたいにコメントでdepthとlistの長さの関係を補足してif文にする方が良かったかも。 | ||
|
||
```py | ||
class Solution: | ||
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: | ||
if not root: | ||
return [] | ||
node_depth_pairs = [(root, 0)] | ||
level_order_values = [] | ||
while node_depth_pairs: | ||
node, depth = node_depth_pairs.pop() | ||
while depth >= len(level_order_values): | ||
level_order_values.append([]) | ||
level_order_values[depth].append(node.val) | ||
if node.right: | ||
node_depth_pairs.append((node.right, depth + 1)) | ||
if node.left: | ||
node_depth_pairs.append((node.left, depth + 1)) | ||
return level_order_values | ||
``` | ||
|
||
## 3rd | ||
|
||
|
||
```py | ||
class Solution: | ||
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: | ||
if not root: | ||
return [] | ||
nodes = [root] | ||
level_order_values = [] | ||
while nodes: | ||
next_level_nodes = [] | ||
values = [] | ||
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. valuesだけだと、同じ深さのnodeの値をまとめた配列、という内容には少し物足りない気がしました。level_valueとかでしょうか? 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. 配列なので |
||
for node in nodes: | ||
values.append(node.val) | ||
if node.left: | ||
next_level_nodes.append(node.left) | ||
if node.right: | ||
next_level_nodes.append(node.right) | ||
nodes = next_level_nodes | ||
level_order_values.append(values) | ||
return level_order_values | ||
``` |
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.
個人的にはappend_if_existsで左右のノードを調べるほうが良いかと思いました。
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.
関数名はもう少しあるかもですが、こんな感じですかね?発想なかったんですがなるほどと思いました。スッキリすると思います