-
Notifications
You must be signed in to change notification settings - Fork 0
Create 103. Binary Tree Zigzag Level Order Traversal.md #10
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
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,185 @@ | ||||||
| ## DFSによる解答 | ||||||
| ### 1回目 (29m25s) | ||||||
| かなり悩んだ。どの順番で何をすべきかを整理するのに時間がかかった。 | ||||||
| →BFSを検討するべき。 | ||||||
|
|
||||||
| ```python | ||||||
| class Solution: | ||||||
| def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: | ||||||
| if not root: | ||||||
| return [] | ||||||
|
|
||||||
| reverse = 1 | ||||||
| zigzag_level_ordered_nodes = [] | ||||||
| next_nodes = deque([(root)]) | ||||||
|
|
||||||
| while next_nodes: | ||||||
| level_nodes = [] | ||||||
| for _ in range(len(next_nodes)): | ||||||
| if reverse == 1: | ||||||
| node = next_nodes.popleft() | ||||||
| if node.left: next_nodes.append(node.left) | ||||||
| if node.right: next_nodes.append(node.right) | ||||||
|
|
||||||
| if reverse == -1: | ||||||
| node = next_nodes.pop() | ||||||
| if node.right: next_nodes.appendleft(node.right) | ||||||
| if node.left: next_nodes.appendleft(node.left) | ||||||
|
|
||||||
|
|
||||||
| level_nodes.append(node.val) | ||||||
|
|
||||||
| reverse *= -1 | ||||||
| zigzag_level_ordered_nodes.append(level_nodes) | ||||||
|
|
||||||
| return zigzag_level_ordered_nodes | ||||||
| ``` | ||||||
|
|
||||||
| 上記のコードを基にセルフ修正。 | ||||||
| 命名と、reverseに意味がない(なにがreverseなのかわからない)ため、 | ||||||
| 階数(level)を数え上げていく方法に変更。 | ||||||
| levelは1始まりにしても良いかもしれない。 | ||||||
|
|
||||||
| ### 2回目 | ||||||
| ```python | ||||||
| class Solution: | ||||||
| def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: | ||||||
| if not root: | ||||||
| return [] | ||||||
|
|
||||||
| level = 0 | ||||||
| zigzag_ordered_level_nodes = [] | ||||||
| next_level_nodes = deque([root]) | ||||||
|
|
||||||
| while next_level_nodes: | ||||||
| level_nodes = [] | ||||||
| for _ in range(len(next_level_nodes)): | ||||||
| if level % 2 == 0: | ||||||
| node = next_level_nodes.popleft() | ||||||
| if node.left: next_level_nodes.append(node.left) | ||||||
| if node.right: next_level_nodes.append(node.right) | ||||||
| else: | ||||||
| node = next_level_nodes.pop() | ||||||
| if node.right: next_level_nodes.appendleft(node.right) | ||||||
| if node.left: next_level_nodes.appendleft(node.left) | ||||||
|
|
||||||
| level_nodes.append(node.val) | ||||||
| level += 1 | ||||||
| zigzag_ordered_level_nodes.append(level_nodes) | ||||||
|
|
||||||
| return zigzag_ordered_level_nodes | ||||||
| ``` | ||||||
|
|
||||||
| コメントを基に、level_nodes_valuesに変更。少し変数名が長く(ややこしく)なりすぎているかもしれない。 | ||||||
| 特にzigzag_ordered_level_nodes。 | ||||||
| ### 3回目 | ||||||
| ```python | ||||||
| class Solution: | ||||||
| def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: | ||||||
| if not root: | ||||||
| return [] | ||||||
| level = 0 | ||||||
| zigzag_ordered_level_nodes = [] | ||||||
| next_level_nodes = deque([root]) | ||||||
|
|
||||||
| while next_level_nodes: | ||||||
| level_nodes_values = [] | ||||||
| for _ in range(len(next_level_nodes)): | ||||||
| if level % 2 == 0: | ||||||
| node = next_level_nodes.popleft() | ||||||
| if node.left: next_level_nodes.append(node.left) | ||||||
| if node.right: next_level_nodes.append(node.right) | ||||||
| else: | ||||||
| node = next_level_nodes.pop() | ||||||
| if node.right: next_level_nodes.appendleft(node.right) | ||||||
| if node.left: next_level_nodes.appendleft(node.left) | ||||||
|
|
||||||
| level_nodes_values.append(node.val) | ||||||
| level += 1 | ||||||
| zigzag_ordered_level_nodes.append(level_nodes_values) | ||||||
|
|
||||||
| return zigzag_ordered_level_nodes | ||||||
| ``` | ||||||
|
|
||||||
|
|
||||||
| BFSの方が理解しやすかった。 | ||||||
| ## BFSによる解答 | ||||||
| ```python | ||||||
| class Solution: | ||||||
| def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: | ||||||
| if not root: | ||||||
| return [] | ||||||
| next_level_nodes = deque([root]) | ||||||
| level = 0 | ||||||
| zigzag_ordered_level_nodes = [] | ||||||
|
|
||||||
| while next_level_nodes: | ||||||
| level_node_values = [] | ||||||
| for _ in range(len(next_level_nodes)): | ||||||
| node = next_level_nodes.popleft() | ||||||
| if node.left: next_level_nodes.append(node.left) | ||||||
| if node.right: next_level_nodes.append(node.right) | ||||||
| level_node_values.append(node.val) | ||||||
|
|
||||||
| if level % 2: | ||||||
| level_node_values.reverse() | ||||||
| level += 1 | ||||||
| zigzag_ordered_level_nodes.append(level_node_values) | ||||||
| return zigzag_ordered_level_nodes | ||||||
| ``` | ||||||
|
|
||||||
|
|
||||||
| ### 4回目 | ||||||
| ahayashiさんのアドバイスを基に書き直し。level_orered_valsへの値の追加以外の処理を共通化。 | ||||||
| ```python | ||||||
| class Solution: | ||||||
| def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: | ||||||
| if not root: return [] | ||||||
| zigzag_ordered_level_nodes = [] | ||||||
| next_level_nodes = deque([(root)]) | ||||||
|
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. これで良いですね。わざわざtupleにする必要はないと思います。
Suggested change
|
||||||
| level = 1 | ||||||
|
|
||||||
| while next_level_nodes: | ||||||
| level_ordered_vals = deque() | ||||||
| for _ in range(len(next_level_nodes)): | ||||||
| node = next_level_nodes.popleft() | ||||||
|
|
||||||
| if level % 2: | ||||||
| level_ordered_vals.append(node.val) | ||||||
| else: | ||||||
| level_ordered_vals.appendleft(node.val) | ||||||
|
|
||||||
| if node.left: next_level_nodes.append(node.left) | ||||||
| if node.right: next_level_nodes.append(node.right) | ||||||
| zigzag_ordered_level_nodes.append(level_ordered_vals) | ||||||
| level += 1 | ||||||
|
|
||||||
| return zigzag_ordered_level_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. ListのListではなくてdeque objectのListが返っていますね。
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. list(zigzag_ordered_level_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.
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. ありがとうございます。 |
||||||
| ``` | ||||||
|
|
||||||
| 補助関数を用いた方法 (levelの値に基づいて最終結果の対応indexに値を加えていく, reverseなし) | ||||||
| ```python | ||||||
| class Solution: | ||||||
| def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: | ||||||
| # DFS | ||||||
| if not root: return [] | ||||||
| zigzag_ordered_level_nodes = [deque()] | ||||||
|
|
||||||
| def zigzagLevelOrder_helper(node, level): #Note:level (int) counts from 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. 関数名はcamelCaseかsnake_caseのどちらかにして欲しいです。
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. ありがとうございます、混じってますね。気をつけます。 |
||||||
| while len(zigzag_ordered_level_nodes) <= level: | ||||||
| zigzag_ordered_level_nodes.append(deque()) | ||||||
| if level % 2: | ||||||
| zigzag_ordered_level_nodes[level].appendleft(node.val) | ||||||
| else: | ||||||
| zigzag_ordered_level_nodes[level].append(node.val) | ||||||
|
|
||||||
| if node.left: zigzagLevelOrder_helper(node.left, level + 1) | ||||||
| if node.right: zigzagLevelOrder_helper(node.right, level + 1) | ||||||
|
|
||||||
| zigzagLevelOrder_helper(root, 0) | ||||||
| return zigzag_ordered_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.
なんか必要以上に複雑なことをしている感想を持ちました。queueへの要素の追加、取り出しをlevelの偶奇数に応じて使い分けていて、読むのも結構大変でした。
next_level_nodesへの要素の追加、取り出しの処理は共通にして、level_nodes_valuesへの追加のタイミングでappendとappendleftを使い分ける方がシンプルかなと思います。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.
ご返信遅くなってしまいすみません。(自分の頭の中がパズル化していたので)他の方がどのように考えたのか気になったので、非常に参考になりました。自分の頭でも整理し直して、より簡潔に書き直すことができたと思います。