BFS with Queue
Intuition
Level order traversal is the textbook application of breadth-first search. We use a queue to process nodes level by level. The key technique is to record the size of the queue at the start of each level -- this tells us exactly how many nodes belong to the current level. We dequeue that many nodes, collect their values, and enqueue their children for the next level. This continues until the queue is empty.
Algorithm
- If the root is null, return an empty list.
- Initialize a queue with the root and an empty result list.
- While the queue is not empty, record its current size as the level size.
- Create a list for the current level.
- Dequeue exactly levelSize nodes, adding each value to the current level list.
- For each dequeued node, enqueue its non-null left and right children.
- Add the current level list to the result.
- Return the result.
O(n)SpaceO(n)Code (C++ · Java · Python · Go)
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> result;
if (root == nullptr) return result;
queue<TreeNode*> q;
q.push(root);
while (!q.empty()) {
int size = q.size();
vector<int> level;
for (int i = 0; i < size; i++) {
TreeNode* node = q.front();
q.pop();
level.push_back(node->val);
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
}
result.push_back(level);
}
return result;
}
};class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) return result;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> level = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
level.add(node.val);
if (node.left != null) queue.offer(node.left);
if (node.right != null) queue.offer(node.right);
}
result.add(level);
}
return result;
}
}from collections import deque
def levelOrder(root: Optional[TreeNode]) -> list[list[int]]:
if not root:
return []
result = []
queue = deque([root])
while queue:
level = []
for _ in range(len(queue)):
node = queue.popleft()
level.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(level)
return resultfunc levelOrder(root *TreeNode) [][]int {
if root == nil {
return [][]int{}
}
var result [][]int
queue := []*TreeNode{root}
for len(queue) > 0 {
size := len(queue)
level := make([]int, 0, size)
for i := 0; i < size; i++ {
node := queue[0]
queue = queue[1:]
level = append(level, node.Val)
if node.Left != nil {
queue = append(queue, node.Left)
}
if node.Right != nil {
queue = append(queue, node.Right)
}
}
result = append(result, level)
}
return result
}