title: Binary Tree Level Order Traversal slug: binary-tree-level-order difficulty: medium leetcode_id: 102 leetcode_url: https://leetcode.com/problems/binary-tree-level-order-traversal/ categories: - trees - queue patterns: - bfs description: | Given the `root` of a binary tree, return the level order traversal of its nodes' values (i.e., from left to right, level by level). constraints: | - The number of nodes in the tree is in the range [0, 2000]. - -1000 <= Node.val <= 1000 examples: - input: "root = [3,9,20,null,null,15,7]" output: "[[3],[9,20],[15,7]]" explanation: "Level 0 has 3, level 1 has 9 and 20, level 2 has 15 and 7." - input: "root = [1]" output: "[[1]]" explanation: "Single node at level 0." - input: "root = []" output: "[]" explanation: "Empty tree returns empty list." explanation: approach: | 1. Use a queue for BFS traversal 2. Track the number of nodes at current level 3. Process all nodes at current level before moving to next 4. Add children to queue as we process each node 5. Collect values for each level in a separate list intuition: | BFS naturally visits nodes level by level. By tracking how many nodes are in the queue at the start of each level, we know exactly when one level ends and the next begins. The key insight is that after processing all nodes of level k, the queue contains exactly all nodes of level k+1. common_pitfalls: - title: Not tracking level boundaries description: | Without tracking level size, you can't separate nodes into their levels. Capture queue size at the start of each level iteration. wrong_approach: "Processing queue without counting level size" correct_approach: "level_size = len(queue); process level_size nodes" - title: Forgetting null check description: | Empty tree (null root) should return empty list, not cause an error. - title: Using list as queue description: | Using list.pop(0) is O(n). Use collections.deque for O(1) popleft. key_takeaways: - BFS with queue is the standard for level-order traversal - Track level size to group nodes by level - This pattern extends to many tree problems (zigzag, right side view, etc.) - deque is more efficient than list for queue operations time_complexity: "O(n)" space_complexity: "O(n)" complexity_explanation: | Time: Visit each node exactly once. Space: Queue holds at most one level of nodes, which is O(n) in worst case (complete tree). solutions: - approach_name: BFS with Queue (Optimal) is_optimal: true code: | from collections import deque class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def level_order(root: TreeNode | None) -> list[list[int]]: if not root: return [] result = [] queue = deque([root]) while queue: level_size = len(queue) level_values = [] for _ in range(level_size): node = queue.popleft() level_values.append(node.val) if node.left: queue.append(node.left) if node.right: queue.append(node.right) result.append(level_values) return result explanation: | Process nodes level by level using a queue. Track level size to know when to start a new level list. - approach_name: DFS with Level Tracking is_optimal: false code: | def level_order(root: TreeNode | None) -> list[list[int]]: result = [] def dfs(node: TreeNode | None, level: int) -> None: if not node: return if level == len(result): result.append([]) result[level].append(node.val) dfs(node.left, level + 1) dfs(node.right, level + 1) dfs(root, 0) return result explanation: | DFS alternative: pass level as parameter and append to appropriate list. Same time complexity but uses recursion stack space.