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