remove duplicate question file
This commit is contained in:
@@ -1,135 +0,0 @@
|
|||||||
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.
|
|
||||||
Reference in New Issue
Block a user