-
Notifications
You must be signed in to change notification settings - Fork 0
103 binary tree zigzag level order traversal medium #22
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?
103 binary tree zigzag level order traversal medium #22
Conversation
|
|
||
| class Solution: | ||
| def zigzagLevelOrder(self, root: TreeNode | None) -> list[list[int]]: | ||
| zigzag_level_order_vals: list[list[int]] = [] # deque |
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.
dequeコメントはミスでしょうか
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.
レビューありがとうございます。
そうです。ご指摘ありがとうございます。
| zigzag_vals.reverse() | ||
| zigzag_level_order_vals.append(zigzag_vals) | ||
| nodes = next_level_nodes | ||
| next_level_nodes = [] |
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.
これはループの最初に持ってきた方が読みやすいと思います。そうするとL20も消すことができます。
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.
確かにそうですね。zigzag_valsともそろった方が読みやすいと感じました。
| next_level_nodes.append(node.right) | ||
|
|
||
| if not next_level_nodes: | ||
| return zigzag_level_order_vals |
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.
個人的には、これはnext_level_nodes.appendの段階でnode.leftやnode.rightがNoneかどうかをチェックする処理を入れるなどして、ループの最後に持っていきたいです。
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.
nodeを取り出したときにNoneを判定するようにすると、
if root is None:...if node.left is not None:...if node.right is not None:...
という3つのif文が1つになるので、より簡潔だなと感じてこのようにしました。
以下のようにすれば、最後にreturnできますね。
from collections import deque
class Solution:
def zigzagLevelOrder(self, root: TreeNode | None) -> list[list[int]]:
zigzag_level_order_vals: list[list[int]] = []
nodes = [root]
level = 0
while nodes:
next_level_nodes = []
zigzag_vals = deque([])
for node in nodes:
if node is None:
continue
# from left to right
if level % 2 == 0:
zigzag_vals.append(node.val)
else:
zigzag_vals.appendleft(node.val)
next_level_nodes.append(node.left)
next_level_nodes.append(node.right)
nodes = next_level_nodes
if zigzag_vals:
zigzag_level_order_vals.append(list(zigzag_vals))
level += 1
return zigzag_level_order_valsThere 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.
あ、そちらの方が良さそうですね!
| node, level = nodes_queue.popleft() | ||
| if node is None: | ||
| continue | ||
| while len(zigzag_node_vals) <= level: |
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.
好みかもしれませんが、個人的にはwhileではなくifの方が分かりやすい気がします。
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.
ifだと「条件が満たされれば1つ要素を追加する」という意味になりますが、while だと「条件が満たされるまで要素を追加する」という意味になってより適切だと感じました。
(もちろん、こちらのコードではどちらでも動作しますが)
| continue | ||
| while len(zigzag_node_vals) <= level: | ||
| zigzag_node_vals.append(deque([])) | ||
| if level % 2 == 0: # from left to right; FIFO |
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.
FIFOはFirst In First Outの略で、今回の問題においてはOutの順番が重要であるわけではなく、単に左から追加する、右から追加するというのが重要になるだけなので、ここのコメントのFIFOとL31のLIFOはない方が読みやすいと思いました。
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.
確かにpopするわけではなく、リストをそのまま返すので、その方が適切ですね。
|
すでにコメントがついている点以外は問題ないと思いました。 |
問題へのリンク
103. Binary Tree Zigzag Level Order Traversal
言語
Python
問題の概要
自分の解法
step1
O(n)O(n)step2
step3
レベルごとに走査を行う方法(
step3_1.py)。直感的だが、ネストが深くなる。リストを再代入していくのもあまり良くないかも。
next_level_nodesの初期化をループの外で行い、ループの最後で空にするようにしたlevelの初期化をループの外で行い、ループの最後でインクリメントするようにしたnodesをキューで管理して、ネストを1つ浅くする方法(step3_2.py)reverseを使う方法(step3_3.py)dequeを使わずに、普通のリストで値を保持し、reverseで並び替える方法step4 (FB)
別解・模範解答
DFS
再帰関数を用いてグラフを走査していく。
各レベルごとのノードのリストを
dequeとして保持して、levelが奇数のときは走査した順、つまりFIFOの順にノードを追加していく。levelが偶数のときは逆順、つまりLIFOの順にノードを追加していく。最後に
dequeをリストに変換して返す。時間計算量:
O(n)空間計算量:
O(n)