diff --git a/problems/102.binary-tree-level-order-traversal/memo.md b/problems/102.binary-tree-level-order-traversal/memo.md new file mode 100644 index 0000000..3e11d4e --- /dev/null +++ b/problems/102.binary-tree-level-order-traversal/memo.md @@ -0,0 +1,32 @@ +## step1 +- 読解の自信がない +- rootからのstepごとにNodeのvalueを配列に入れて返せば良いと理解した + - その際に左から右に返す +- 幅優先探索で解けば良さそう +- 特に苦労なく書けた +- 方針として毎回level毎に新しくfrontierを作るか、levelもfrontierに入れて管理するか迷ったが毎回level毎に作った方がわかりやすそうだと思ったので現在の実装にした +- `while True`が自分の中でだいぶ抵抗があった + - 今回の主役はfrontierにしたいのだが、`while frontier`とすると毎回末尾でfrontierが空かどうかを判定して次の階層にいく必要が出てきそうなのでやめた + - 処理のまとまり的にも1つの階層を処理して次の階層が終わるまで処理するという2重のloopっぽい動きと捉えたので1つのwhileに頑張ってまとめようとしなかった + +## step2 +- 時間計算量はO(N),空間計算量もO(N)だと思う + - 答えを1行ずつ出していいなら空間計算量はO(logN)になると思う +- 他の人のコードを読む +- https://github.com/Shoichifunyu/shofun/pull/20 + - `ret`が気になって調べたが最終的に返す値を一時的に入れておく変数でC/C++系でよく使われてたとのこと + - 自分もこの問題の時に`result`と書こうとしたので気持ちは分かるが少しでも意味をつけようと思って`level_order_values`とした + - 関数名をつける時に`build`も思いつけるようにしておきたいと思った +- https://github.com/mamo3gr/arai60/pull/25/changes + - 再帰でも書けるのかなと一瞬思ったが、最後に配列で返す必要があって難しそうだなと思ったがstep2を見てわかりやすかったし短くかけてていいなと思った + - 階層ごとに処理をする場合はwhileでpopしなくてもforでも良いことに気づいた + - `if だと「インデックスが範囲外になる場合のずれは高々1だけのはずだ」という、外部のロジックへの依存・信頼が必要になり、読むときも俯瞰的に読まないといけません。while であれば、「配列長が足りなければ足りるまで伸ばす」というシンプルで独立したロジックとして完結しているため、局所的にパッと見たときの安心感があります。`確かに外部のロジックに依存して動くよりは独立して動いた方がいいと思った。こういう観点でも考えられるようにしたい。 +- https://github.com/plushn/SWE-Arai60/pull/26 + - `itertools.chain`初めて知った + - https://docs.python.org/ja/3/library/itertools.html#itertools.chain + - `current_level`の命名がいいなと思ったfrontierよりその階層のものという情報が足される +- step2は再帰で書いてみる + +## step3 +- step1と同じやり方でforとwhile Trueの部分を修正して書いた + diff --git a/problems/102.binary-tree-level-order-traversal/step1.py b/problems/102.binary-tree-level-order-traversal/step1.py new file mode 100644 index 0000000..8e0e53c --- /dev/null +++ b/problems/102.binary-tree-level-order-traversal/step1.py @@ -0,0 +1,43 @@ +# +# @lc app=leetcode id=102 lang=python3 +# +# [102] Binary Tree Level Order Traversal +# + +# @lc code=start +# 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 +import collections + + +class Solution: + def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: + level_order_values = [] + if root is None: + return level_order_values + frontier = collections.deque() + frontier.append(root) + + while True: + order_values = [] + next_frontier = collections.deque() + while frontier: + node = frontier.popleft() + order_values.append(node.val) + if node.left: + next_frontier.append(node.left) + if node.right: + next_frontier.append(node.right) + level_order_values.append(order_values) + if not next_frontier: + break + frontier = next_frontier + + return level_order_values + + +# @lc code=end diff --git a/problems/102.binary-tree-level-order-traversal/step2.py b/problems/102.binary-tree-level-order-traversal/step2.py new file mode 100644 index 0000000..699fdbd --- /dev/null +++ b/problems/102.binary-tree-level-order-traversal/step2.py @@ -0,0 +1,34 @@ +# +# @lc app=leetcode id=102 lang=python3 +# +# [102] Binary Tree Level Order Traversal +# + +# @lc code=start +# 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 levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: + level_order_values = [] + if root is None: + return level_order_values + + def traverse(node: TreeNode, level: int): + while level >= len(level_order_values): + level_order_values.append([]) + + level_order_values[level].append(node.val) + if node.left: + traverse(node.left, level + 1) + if node.right: + traverse(node.right, level + 1) + + traverse(root, 0) + return level_order_values + + +# @lc code=end diff --git a/problems/102.binary-tree-level-order-traversal/step3.py b/problems/102.binary-tree-level-order-traversal/step3.py new file mode 100644 index 0000000..402dde5 --- /dev/null +++ b/problems/102.binary-tree-level-order-traversal/step3.py @@ -0,0 +1,37 @@ +# +# @lc app=leetcode id=102 lang=python3 +# +# [102] Binary Tree Level Order Traversal +# + +# @lc code=start +# 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 levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: + level_order_values = [] + if root is None: + return level_order_values + + current_level = [root] + while current_level: + current_values = [] + next_level = [] + for current in current_level: + current_values.append(current.val) + if current.left: + next_level.append(current.left) + if current.right: + next_level.append(current.right) + + level_order_values.append(current_values) + current_level = next_level + + return level_order_values + + +# @lc code=end