-
Notifications
You must be signed in to change notification settings - Fork 0
Solved Arai60/102. Binary Tree Level Order Traversal #26
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,103 @@ | ||
## Step 1. Initial Solution | ||
|
||
- BFSで探せば良いが、同じ深さをまとめて処理する方が分かりやすそう | ||
- while文の中を同じ深さの処理にする | ||
- 二重ループになるが、処理は分かりやすい | ||
|
||
```python | ||
# 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]]: | ||
if root is None: | ||
return [] | ||
current_level_nodes: List[TreeNode] = [root] | ||
result: List[List[int]] = [] | ||
while current_level_nodes: | ||
node_value_list: List[int] = [] | ||
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. ちなみにPython3.9からは小文字の方が推奨になったようです。個人的には、LeetCodeの関数定義はそのまま |
||
next_level_nodes: List[TreeNode] = [] | ||
for node in current_level_nodes: | ||
node_value_list.append(node.val) | ||
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. リスト内包表記で |
||
if node.left is not None: | ||
next_level_nodes.append(node.left) | ||
if node.right is not None: | ||
next_level_nodes.append(node.right) | ||
result.append(node_value_list) | ||
current_level_nodes = next_level_nodes | ||
return result | ||
``` | ||
|
||
### Complexity Analysis | ||
|
||
- 時間計算量:O(n) | ||
- 空間計算量:O(n) | ||
|
||
## Step 2. Alternatives | ||
|
||
- 深さを保持しておく方法 | ||
|
||
```python | ||
class Solution: | ||
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: | ||
if root is None: | ||
return [] | ||
nodes_and_depths: deque[Tuple[TreeNode, int]] = deque([(root, 0)]) | ||
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. 細かいですが、関数名がlevelなのでdepthつかわずにlevelでもいいかもです |
||
result: List[List[int]] = [[]] | ||
while nodes_and_depths: | ||
node, depth = nodes_and_depths.popleft() | ||
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)) | ||
if len(result) <= depth: | ||
result.append([]) | ||
result[depth].append(node.val) | ||
return result | ||
``` | ||
|
||
- 変数名はもう少し考えても良いのかも | ||
- resultの代わりにlevel_ordered_values | ||
- https://github.com/Fuminiton/LeetCode/pull/26/files#diff-c9ad89199edb3e781ec524a54d5b5bd52c8baabcc71b3db537a3d4aeda37c9e6R58 | ||
- 下の書き方も変数が減って楽になる | ||
- 個人的には悪くないと思った | ||
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. 個人的にはあまり好きではないですが、長さが短ければこれでもいいのかもしれません。 |
||
- https://github.com/sakupan102/arai60-practice/pull/27/files#r1597353212 | ||
|
||
```python | ||
while nodes: | ||
level_ordered_values.append([]) | ||
for node in nodes: | ||
level_ordered_values[-1].append(node.val) | ||
``` | ||
|
||
- フィルター関数を用いるのもあり | ||
- `nodes = list(filter(None, nodes))` | ||
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. この書き方がソフトウェアエンジニアの常識に含まれているか、あまり自信がありませんでした。 X (Twitter) でアンケート取ってみます。 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. 別に Python を普段書いていないならば知らなくて当然と思いますが、 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. 念のため補足すると、 filter() 関数の第一引数に None を渡した場合、第二引数に渡された値から None を取り除いた値を返す、という挙動が、平均的なソフトウェアエンジニアにとって既知のものであるか、読みやすいかという点を気にしていました。問題なさそうということであれば、大丈夫だと思います。 |
||
- https://github.com/Fuminiton/LeetCode/pull/26/files#diff-c9ad89199edb3e781ec524a54d5b5bd52c8baabcc71b3db537a3d4aeda37c9e6R64 | ||
- if文で改行しないのはたまにやりたくなるが読んでいると一瞬びっくりする | ||
- https://github.com/TORUS0818/leetcode/pull/28/files#diff-8c44f4aded8e694c335a78471f1f2b470fbd42a28276462da15a2f4ba70d3810R199 | ||
|
||
## Step 3. Final Solution | ||
|
||
- あまり馴染みがなかったのでfilterを使って実装 | ||
- ちょっと変数名が長すぎて読みにくい印象になってしまった | ||
|
||
```python | ||
class Solution: | ||
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: | ||
if root is None: | ||
return [] | ||
level_ordered_values: List[List[int]] = [] | ||
nodes_to_order: Deque[TreeNode] = deque([root]) | ||
while nodes_to_order: | ||
level_ordered_values.append([]) | ||
for _ in range(len(nodes_to_order)): | ||
node = nodes_to_order.popleft() | ||
level_ordered_values[-1].append(node.val) | ||
nodes_to_order.append(node.left) | ||
nodes_to_order.append(node.right) | ||
nodes_to_order = deque(filter(None, nodes_to_order)) | ||
return level_ordered_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. 読みやすかったです。 |
||
``` |
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.
あまり list というデータ構造であることを示す特別な意味がない (vs. stack / queue) ように思うので、単に複数形で node_values などのほうがよいかなと思いました。next_level_nodes とも align しているので。