🧠
Brute Force (Level Order Traversal with Extra Queue)
💡 This approach uses a classic BFS with a queue to traverse the tree level by level and connect nodes. It is straightforward and helps beginners understand the problem structure before optimizing space.
Intuition
Traverse the tree level by level using a queue. For each level, connect nodes from left to right by setting their next pointers. Use extra space proportional to the maximum number of nodes at any level.
Algorithm
- Initialize a queue and enqueue the root node if it exists.
- While the queue is not empty, process nodes level by level:
- For each level, iterate through all nodes currently in the queue, linking each node's next pointer to the next node in the queue for that level.
- Enqueue the children of the current level's nodes for the next iteration.
💡 The challenge is to carefully link nodes within the same level before moving to the next, which is easier with a queue but uses extra memory.
from collections import deque
class Node:
def __init__(self, val=0, left=None, right=None, next=None):
self.val = val
self.left = left
self.right = right
self.next = next
def connect(root):
if not root:
return None
queue = deque([root])
while queue:
size = len(queue)
prev = None
for _ in range(size):
node = queue.popleft()
if prev:
prev.next = node
prev = node
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
prev.next = None
return root
# Example usage:
# root = Node(1, Node(2, Node(4), Node(5)), Node(3, None, Node(7)))
# connected_root = connect(root)
# print(connected_root.next) # Should be None since root's next is always None
Line Notes
if not root:Handle empty tree edge case immediately
queue = deque([root])Initialize queue with root to start BFS
size = len(queue)Determine number of nodes at current level
for _ in range(size):Process all nodes at this level
node = queue.popleft()Get the next node in the current level
if prev:Link previous node's next to current node
prev.next = NoneLast node in level points to None
if node.left:Add left child to queue for next level
if node.right:Add right child to queue for next level
import java.util.*;
class Node {
public int val;
public Node left;
public Node right;
public Node next;
public Node() {}
public Node(int val) {
this.val = val;
}
public Node(int val, Node left, Node right, Node next) {
this.val = val;
this.left = left;
this.right = right;
this.next = next;
}
}
public class Solution {
public Node connect(Node root) {
if (root == null) return null;
Queue<Node> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
Node prev = null;
for (int i = 0; i < size; i++) {
Node node = queue.poll();
if (prev != null) {
prev.next = node;
}
prev = node;
if (node.left != null) queue.offer(node.left);
if (node.right != null) queue.offer(node.right);
}
prev.next = null;
}
return root;
}
// Example main to test
public static void main(String[] args) {
Node root = new Node(1,
new Node(2, new Node(4), new Node(5), null),
new Node(3, null, new Node(7), null),
null);
Solution sol = new Solution();
sol.connect(root);
System.out.println(root.next); // Should print null since root's next is always null
}
}
Line Notes
if (root == null) return null;Handle empty tree quickly
Queue<Node> queue = new LinkedList<>();Initialize queue for BFS
queue.offer(root);Start BFS with root node
int size = queue.size();Number of nodes at current level
for (int i = 0; i < size; i++) {Process all nodes in current level
Node node = queue.poll();Get next node in level
if (prev != null) { prev.next = node; }Link previous node's next to current
prev.next = null;Last node in level points to null
if (node.left != null) queue.offer(node.left);Add left child for next level
if (node.right != null) queue.offer(node.right);Add right child for next level
#include <iostream>
#include <queue>
using namespace std;
class Node {
public:
int val;
Node* left;
Node* right;
Node* next;
Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}
};
Node* connect(Node* root) {
if (!root) return nullptr;
queue<Node*> q;
q.push(root);
while (!q.empty()) {
int size = q.size();
Node* prev = nullptr;
for (int i = 0; i < size; i++) {
Node* node = q.front(); q.pop();
if (prev) prev->next = node;
prev = node;
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
}
prev->next = nullptr;
}
return root;
}
// Example usage
int main() {
Node* root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
root->left->right = new Node(5);
root->right->right = new Node(7);
connect(root);
cout << (root->next == nullptr ? "null" : "not null") << endl; // Should print null since root's next is always null
return 0;
}
Line Notes
if (!root) return nullptr;Return immediately if tree is empty
queue<Node*> q;Queue to hold nodes for BFS
q.push(root);Start BFS with root node
int size = q.size();Number of nodes at current level
for (int i = 0; i < size; i++) {Process all nodes at this level
Node* node = q.front(); q.pop();Get next node in current level
if (prev) prev->next = node;Link previous node's next to current
prev->next = nullptr;Last node in level points to nullptr
if (node->left) q.push(node->left);Add left child for next level
if (node->right) q.push(node->right);Add right child for next level
class Node {
constructor(val, left = null, right = null, next = null) {
this.val = val;
this.left = left;
this.right = right;
this.next = next;
}
}
function connect(root) {
if (!root) return null;
const queue = [root];
while (queue.length > 0) {
let size = queue.length;
let prev = null;
for (let i = 0; i < size; i++) {
const node = queue.shift();
if (prev) prev.next = node;
prev = node;
if (node.left) queue.push(node.left);
if (node.right) queue.push(node.right);
}
prev.next = null;
}
return root;
}
// Example usage:
// const root = new Node(1, new Node(2, new Node(4), new Node(5)), new Node(3, null, new Node(7)));
// connect(root);
// console.log(root.next); // Should print null since root's next is always null
Line Notes
if (!root) return null;Handle empty tree edge case
const queue = [root];Initialize queue with root for BFS
let size = queue.length;Number of nodes at current level
for (let i = 0; i < size; i++) {Process all nodes at this level
const node = queue.shift();Dequeue next node in level
if (prev) prev.next = node;Link previous node's next to current
prev.next = null;Last node in level points to null
if (node.left) queue.push(node.left);Add left child for next level
if (node.right) queue.push(node.right);Add right child for next level
TimeO(n)
SpaceO(w) where w is the maximum width of the tree
Each node is visited once, and the queue holds at most the maximum number of nodes at any level.
💡 For a tree with 20 nodes and max width 5, this means about 20 operations and queue size up to 5.
Interview Verdict: Accepted but uses extra space
This approach is easy to understand and implement but does not meet the constant space requirement, so it's a good starting point but not the final solution.