diff --git "a/\347\253\266\346\212\200\343\203\227\343\203\255\345\260\261\346\264\273\351\203\250PR\347\224\250/103. Binary Tree Zigzag Level Order Traversal.md" "b/\347\253\266\346\212\200\343\203\227\343\203\255\345\260\261\346\264\273\351\203\250PR\347\224\250/103. Binary Tree Zigzag Level Order Traversal.md" new file mode 100644 index 0000000..97dfc37 --- /dev/null +++ "b/\347\253\266\346\212\200\343\203\227\343\203\255\345\260\261\346\264\273\351\203\250PR\347\224\250/103. Binary Tree Zigzag Level Order Traversal.md" @@ -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)]) + 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 +``` + +補助関数を用いた方法 (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. + 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 +``` + + + +