diff --git a/102. Binary Tree Level Order Traversal.md b/102. Binary Tree Level Order Traversal.md new file mode 100644 index 0000000..e6cb9b2 --- /dev/null +++ b/102. Binary Tree Level Order Traversal.md @@ -0,0 +1,135 @@ +### Step1 + +- 深さ順に探索できるといえばBFS +- dequeでBFSしているwhile文の中で、ついでにresultに突っ込む方法もありそう +- いただくコメントを予想すると、nodes_val_orderedとnodes_and_depthという変数名が分かりにくい可能性あり + - nodes_and_depthはwhileループの中で次に突っ込むやつだし、単数複数が統一されていないので、next_node_depth_pairsなどがいいかな + - nodes_val_orderedは、pairs_ordered_by_depthなどがいいかな + +```python + +from collections import deque + +class Solution: + def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: + nodes_and_depth = deque() + nodes_and_depth.append((root, 0)) + nodes_val_ordered = [] + while nodes_and_depth: + node, depth = nodes_and_depth.popleft() + if not node: + continue + nodes_val_ordered.append((node.val, depth)) + nodes_and_depth.append((node.left, depth + 1)) + nodes_and_depth.append((node.right, depth + 1)) + result = [] + prev_depth = None + for node, depth in nodes_val_ordered: + if depth != prev_depth: + same_depth_nodes = [] + result.append(same_depth_nodes) + same_depth_nodes.append(node) + prev_depth = depth + return result +``` + +- 探索と同時に突っ込むのを考えて書いてみる + - これで考えると、popleft()をする必要がないのでlistでいいね + - currentはnextとの比較なので、今回は変数名として許容 + +```python + +class Solution: + def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: + current_depth_nodes = [root] + result = [] + while current_depth_nodes: + next_depth_nodes = [] + current_depth_nodes_val = [] + for node in current_depth_nodes: + if not node: + continue + current_depth_nodes_val.append(node.val) + next_depth_nodes.append(node.left) + next_depth_nodes.append(node.right) + if current_depth_nodes_val: + result.append(current_depth_nodes_val) + current_depth_nodes = next_depth_nodes + return result +``` + +## Step2 + +- 参照 + - https://github.com/sakupan102/arai60-practice/pull/27/files + - node.depthが同じものを入れるときの処理の選択肢。appendが2回に分かれるのはいまいち(Step1の上のやつもそれを考えて書いた) + - https://discord.com/channels/1084280443945353267/1196472827457589338/1196472926862577745 の22 + - 今回の場合node.leftを入れるタイミングでNoneをチェックしてもよかったか + - https://github.com/hayashi-ay/leetcode/pull/32/files + - 再帰でもかけるのか + - 最初に拡張するときにwhileの方が読むやすいのは確かに +- 再帰でも書いてみる + - depthを持ってるので、突っ込むときにresult[depth]にアクセスすれば、nodesの順番を整えなくてもOK。なぜか気が付かなかった。 + - depth ≥ len(result)の方が好きという意見もあった(不等号の向き)。 + +```python +class Solution: + def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: + def append_nodes_val_to_result(node, depth): + if not node: + return + while len(result) <= depth: + result.append([]) + result[depth].append(node.val) + append_nodes_val_to_result(node.left, depth + 1) + append_nodes_val_to_result(node.right, depth + 1) + + result = [] + append_nodes_val_to_result(root, 0) + return result +``` + +- currentとnextの両方を持つことはせず、配列の要素数でlevelを管理 + +```python +class Solution: + def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: + result = [] + if not root: + return [] + nodes = deque([root]) + while nodes: + result.append([]) + for _ in range(len(nodes)): + node = nodes.popleft() + result[-1].append(node.val) + if node.left: + nodes.append(node.left) + if node.right: + nodes.append(node.right) + return result +``` + +## Step3 + +```python + +from collections import deque + +class Solution: + def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: + if not root: + return [] + nodes = deque([root]) + result = [] + while nodes: + result.append([]) + for _ in range(len(nodes)): + node = nodes.popleft() + result[-1].append(node.val) + if node.left: + nodes.append(node.left) + if node.right: + nodes.append(node.right) + return result +```