🧠
Brute Force (Level Order Traversal with Queue)
💡 This approach uses a classic BFS with a queue to connect nodes level by level. It is intuitive and easy to implement but uses extra space proportional to the maximum number of nodes at any level.
Intuition
Traverse the tree level by level using a queue. For each level, connect nodes from left to right by setting their next pointers. The last node in each level points to NULL.
Algorithm
- Initialize a queue and add the root node.
- While the queue is not empty, process nodes level by level.
- For each level, iterate through all nodes and connect each node's next pointer to the next node in the queue for that level.
- Set the next pointer of the last node in each level to NULL.
💡 The main challenge is to process nodes level by level and connect them correctly, 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:
# Construct tree: 1 -> 2,3 -> 4,5,6,7
root = Node(1, Node(2, Node(4), Node(5)), Node(3, Node(6), Node(7)))
connect(root)
# After connection, root.next should be None, root.left.next should be root.right
print(root.next) # None
print(root.left.next.val) # 3
Line Notes
if not root:Check for empty tree to avoid processing null input
queue = deque([root])Initialize queue with root to start BFS
while queue:Process nodes level by level until queue is empty
size = len(queue)Number of nodes at current level to separate levels
prev = NoneTrack previous node to connect next pointer
node = queue.popleft()Get current node from queue for processing
if prev:If previous node exists, link its next to current node
prev = nodeUpdate previous node to current for next iteration
if node.left:Add left child to queue for next level processing
if node.right:Add right child to queue for next level processing
prev.next = NoneLast node in level points to NULL
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, new Node(6), new Node(7), null),
null);
Solution sol = new Solution();
sol.connect(root);
System.out.println(root.next); // null
System.out.println(root.left.next.val); // 3
}
}
Line Notes
if (root == null) return null;Handle empty tree edge case
Queue<Node> queue = new LinkedList<>();Initialize queue for BFS
queue.offer(root);Add root node to start BFS
while (!queue.isEmpty()) {Process nodes level by level
int size = queue.size();Track number of nodes at current level
Node prev = null;Keep track of previous node to link next pointers
Node node = queue.poll();Retrieve current node from queue
if (prev != null) { prev.next = node; }Connect previous node's next to current node
prev = node;Update previous node
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
prev.next = null;Last node in level points to null
#include <iostream>
#include <queue>
using namespace std;
class Node {
public:
int val;
Node* left;
Node* right;
Node* next;
Node() : val(0), left(NULL), right(NULL), next(NULL) {}
Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}
Node(int _val, Node* _left, Node* _right, Node* _next) : val(_val), left(_left), right(_right), next(_next) {}
};
class Solution {
public:
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,
new Node(2, new Node(4), new Node(5), nullptr),
new Node(3, new Node(6), new Node(7), nullptr),
nullptr);
Solution sol;
sol.connect(root);
cout << (root->next == nullptr) << endl; // 1 (true)
cout << root->left->next->val << endl; // 3
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
while (!q.empty()) {Process each level until queue is empty
int size = q.size();Number of nodes at current level
Node* prev = nullptr;Track previous node to link next pointers
Node* node = q.front(); q.pop();Get current node from queue
if (prev) prev->next = node;Link previous node's next to current node
prev = node;Update previous node
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
prev->next = nullptr;Last node in level points to null
class Node {
constructor(val = 0, 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) {
const 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, new Node(6), new Node(7)));
connect(root);
console.log(root.next); // null
console.log(root.left.next.val); // 3
Line Notes
if (!root) return null;Handle empty tree input
const queue = [root];Initialize queue with root for BFS
while (queue.length > 0) {Process nodes level by level
const size = queue.length;Number of nodes at current level
let prev = null;Track previous node to connect next pointers
const node = queue.shift();Remove node from front of queue
if (prev) prev.next = node;Connect previous node's next to current node
prev = node;Update previous node
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
prev.next = null;Last node in level points to null
We visit each node once, so time is O(n). The queue can hold up to the maximum number of nodes at a level, which is O(n/2) = O(n) in worst case.
💡 For n=20 nodes, this means roughly 20 operations and up to 10 nodes in the queue at once.
Interview Verdict: Accepted
This approach works correctly but uses extra memory, which might be a concern for very large trees.