136 lines
4.2 KiB
YAML
136 lines
4.2 KiB
YAML
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.
|