Any problem involving the traversal of a tree in a level-by-level order can be efficiently solved using this approach. We will use a Queue to keep track of all the nodes of a level before we jump onto the next level. This also means that the space complexity of the algorithm will be O(W)
, where ‘W’ is the maximum number of nodes on any level.
BFS traversal using queue.
public List<List<Integer>> levelOrder(TreeNode root) {
if (root == null) return new ArrayList<>();
List<List<Integer>> result = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
queue.add(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.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
result.add(level);
}
return result;
}
From here we can also keep track of level, or previous pointers to connect siblings.
public TreeNodeNext connect(TreeNodeNext root) {
if (root == null) return root;
Queue<TreeNodeNext> queue = new LinkedList<>();
queue.add(root);
TreeNodeNext prev = null;
while(!queue.isEmpty()) {
int size = queue.size();
for(int i = 0; i < size; i++) {
TreeNodeNext node = queue.poll();
if (prev != null) {
prev.next = node;
}
prev = node;
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
}
return root;
}
The time complexity of the above algorithm is O(N)
, where ‘N’ is the total number of nodes in the tree. This is due to the fact that we traverse each node once.
The space complexity of the above algorithm will be O(N)
as we need to return a list containing the level order traversal. We will also need O(N)
space for the queue. Since we can have a maximum of N/2
nodes at any level (this could happen only at the lowest level), therefore we will need O(N)
space to store them in the queue.