-
Notifications
You must be signed in to change notification settings - Fork 0
Binary_Tree_Zigzag_Level_Order_Traversal #34
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,161 @@ | ||
| ### Step1 | ||
|
|
||
| ```python | ||
|
|
||
| from collections import deque | ||
|
|
||
| class Solution: | ||
| def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: | ||
| nodes_and_depthes = deque([(root, 0)]) | ||
| zigzag_ordered = [] | ||
| prev_depth = None | ||
| from_left = False | ||
| while nodes_and_depthes: | ||
| node, depth = nodes_and_depthes.popleft() | ||
| if not node: | ||
| continue | ||
| if prev_depth != depth: | ||
| if prev_depth and not from_left: | ||
| same_depth_nodes.reverse() | ||
| same_depth_nodes = [] | ||
| from_left = not from_left | ||
| zigzag_ordered.append(same_depth_nodes) | ||
| same_depth_nodes.append(node.val) | ||
| nodes_and_depthes.append((node.left, depth + 1)) | ||
| nodes_and_depthes.append((node.right, depth + 1)) | ||
| prev_depth = depth | ||
| if prev_depth and not from_left: | ||
| same_depth_nodes.reverse() | ||
| return zigzag_ordered | ||
| ``` | ||
|
|
||
| ### Step2 | ||
|
|
||
| https://discord.com/channels/1084280443945353267/1201211204547383386/1219179255615717399 | ||
|
|
||
| - Zigzagじゃない方のStep2の最後で、current_levelとnext_levelを2つ持たず、要素数で管理するやつを自分も書いたが、確かに同じ変数で2種類のものを管理するのでややこしいかも | ||
| - 一般に、同じ変数に複数の役割を持たすのはあまり好ましくないかもと思った | ||
|
|
||
| https://github.com/fhiyo/leetcode/pull/29 | ||
|
|
||
| - left_to_rightという変数名でも良い | ||
| - 突っ込む順番を逆にするより、フラグを立てて後からreverse()の方が遅くなるものの意図が明確で良い | ||
|
|
||
| https://github.com/TORUS0818/leetcode/pull/29 | ||
|
|
||
| - next_levelを持つ実装 | ||
| - 引き継ぎはcurrent_depth_nodesとfrom_leftで、current_depth_nodes_valとnext_depth_nodesの初期化は次の人に任せた | ||
| - 後で気づいたが、next_depth_nodesをwhileの外で持つ必要はない | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: | ||
| if not root: | ||
| return [] | ||
| current_depth_nodes = [root] | ||
| from_left = True | ||
| next_depth_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. 消し忘れとかですかね |
||
| zigzag_ordered = [] | ||
| while current_depth_nodes: | ||
| current_depth_nodes_val = [] | ||
| next_depth_nodes = [] | ||
| for node in current_depth_nodes: | ||
| current_depth_nodes_val.append(node.val) | ||
| if node.left: | ||
| next_depth_nodes.append(node.left) | ||
| if node.right: | ||
| next_depth_nodes.append(node.right) | ||
| if not from_left: | ||
| current_depth_nodes_val.reverse() | ||
| zigzag_ordered.append(current_depth_nodes_val) | ||
| from_left = not from_left | ||
| current_depth_nodes = next_depth_nodes | ||
| return zigzag_ordered | ||
| ``` | ||
|
|
||
| - DFSでの実装 | ||
| - 反転を探索ついでにやるのはかなりややこしくなりそう(可読性も微妙になりそう)なのでやめといた | ||
|
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. 思ったほど酷いことにはならなそうです(これがいいかはおいておいて) # 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 zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
if not root:
return []
node_level_pairs = [(root, 0)]
zigzag_ordered_lists = []
while node_level_pairs:
node, level = node_level_pairs.pop()
while level >= len(zigzag_ordered_lists):
zigzag_ordered_lists.append([])
if level % 2:
zigzag_ordered_lists[level].insert(0, node.val)
else:
zigzag_ordered_lists[level].append(node.val)
if node.right: node_level_pairs.append((node.right, level + 1))
if node.left: node_level_pairs.append((node.left, level + 1))
return zigzag_ordered_lists
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. なるほど、ありがとうございます。(返信遅くなりました) |
||
|
|
||
| ```python | ||
|
|
||
| class Solution: | ||
| def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: | ||
| if not root: | ||
| return [] | ||
| zigzag_ordered = [] | ||
| nodes_stack = [(root, 0)] | ||
| while nodes_stack: | ||
| node, depth = nodes_stack.pop() | ||
| while depth >= len(zigzag_ordered): | ||
| zigzag_ordered.append([]) | ||
| zigzag_ordered[depth].append(node.val) | ||
| if node.right: | ||
| nodes_stack.append((node.right, depth + 1)) | ||
| if node.left: | ||
| nodes_stack.append((node.left, depth + 1)) | ||
| for i in range(len(zigzag_ordered)): | ||
|
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. 次のようにすると、i % 2の判定が不要になります。 for i in range(1, len(zigzag_ordered), 2):
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. なるほど、そういう選択肢はありませんでした、ありがとうございます |
||
| if i % 2: | ||
| zigzag_ordered[i].reverse() | ||
| return zigzag_ordered | ||
| ``` | ||
|
|
||
| ## Step3 | ||
|
|
||
| ```python | ||
|
|
||
| class Solution: | ||
| def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: | ||
| if not root: | ||
| return [] | ||
| result = [] | ||
| current_depth_nodes = [root] | ||
| left_to_right = True | ||
| while current_depth_nodes: | ||
| next_depth_nodes = [] | ||
| values_of_current_depth = [] | ||
| for node in current_depth_nodes: | ||
| values_of_current_depth.append(node.val) | ||
| if node.left: | ||
| next_depth_nodes.append(node.left) | ||
| if node.right: | ||
| next_depth_nodes.append(node.right) | ||
| if not left_to_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. 好みの問題かもですが、Step2の最後のもののように、resultを構築してからreverse()する方が、left_to_rightが不要になるので読みやすくなるように思います。
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. 確かにそうですね、結構パフォーマンスを意識していまいがちですが、実務だと可読性の方が大事だと思うので留意します |
||
| values_of_current_depth.reverse() | ||
| result.append(values_of_current_depth) | ||
| current_depth_nodes = next_depth_nodes | ||
| left_to_right = not left_to_right | ||
| return result | ||
| ``` | ||
|
|
||
| ## Step4 | ||
|
|
||
| - nodchipさんの指摘(same_depth_nodesに全部突っ込んだ後に、zigzag_orderedにsame_depth_nodesを入れた方がわかりやすい)などを反映 | ||
|
|
||
| ```python | ||
|
|
||
| from collections import deque | ||
|
|
||
| class Solution: | ||
| def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: | ||
| if not root: | ||
| return [] | ||
| node_and_depth = deque([(root, 0)]) | ||
| zigzag_ordered = [] | ||
| same_depth_nodes = [] | ||
| prev_depth = None | ||
| while node_and_depth: | ||
| node, depth = node_and_depth.popleft() | ||
| if prev_depth is not None and prev_depth != depth: | ||
| zigzag_ordered.append(same_depth_nodes) | ||
| same_depth_nodes = [] | ||
| same_depth_nodes.append(node.val) | ||
| if node.left: | ||
| node_and_depth.append((node.left, depth + 1)) | ||
| if node.right: | ||
| node_and_depth.append((node.right, depth + 1)) | ||
| prev_depth = depth | ||
| zigzag_ordered.append(same_depth_nodes) | ||
| for i in range(1, len(zigzag_ordered), 2): | ||
| zigzag_ordered[i].reverse() | ||
| return zigzag_ordered | ||
| ``` | ||
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.
same_depth_nodesがzigzag_orderedの末尾の要素の状態で、same_depth_nodesに要素を追加していくという処理が直感的ではないように感じました。same_depth_nodesに要素を追加したあとで、zigzag_orderedの末尾に追加したほうが、より分かりやすいコードになると思いました。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.
ありがとうございます。
このほうが場合わけがいらず実装が簡潔になるのでこうしたのですが、確かに書いてる時にわかりにくいかもとなんとなく思ってました。