We have a perfect binary tree, meaning every internal node has exactly two children and all leaves sit at the same depth. Each node has an extra next pointer that we need to wire up so it points to the node immediately to its right on the same level. The rightmost node on each level should have next = null.
The "perfect binary tree" guarantee is what makes this problem tractable. Every level is completely full, so we can predict which nodes are neighbors on each level without handling missing children or uneven subtrees. The general version, where the tree can have any shape, is harder because a node's right neighbor on the same level might be several subtrees away.
Two kinds of connections need to be made: nodes that share a parent (like 4 and 5) and nodes that have different parents (like 5 and 6). The second kind is what the algorithm has to be careful about.
Number of nodes in range [0, 2^12 - 1]. Up to 4095 nodes, small enough that any O(n) approach is fast. Time is not the constraint here.Perfect binary tree. If a node has a left child, it has a right child too, and a node's neighbor on the same level always has children when this node does. This regularity is what makes the O(1) space approach possible.We need to connect nodes on the same level, and BFS processes nodes one level at a time. A standard level-order traversal with a queue lets us link consecutive nodes as we go.
We process the queue one level at a time, recording the level's size before we start. For each node except the last on that level, we set its next pointer to the node now at the front of the queue, which is its right neighbor. The last node on each level keeps next = null.
Loading animation...
BFS works but the queue costs O(n) extra space. The next approach drops the queue by using recursion, relying on a parent's next pointer being set before we reach its children.
From any node, there are exactly two next connections to make among its children:
next points to the right child. Both children belong to the same node, so this is a direct assignment.next points to the left child of the parent's next node, for example 5 points to 6 because 5's parent (2) has next pointing to 3, and 3's left child is 6.The cross-parent connection depends on the parent's next already being set. Processing the tree in pre-order (node, then left subtree, then right subtree) provides that ordering: a node's next is wired up while we process its parent, before we ever descend into the node itself.
When we process a node, its own next is already correct. The root has next = null from the start. For any other node, its next was assigned while we processed its parent (one of the two connection lines above), and the parent was processed before this node because pre-order visits a node before its subtrees. So node.next.left is always a valid neighbor when node.next is not null.
node.left.next = node.right.node.right.next = node.next.left.Loading animation...
The recursive version still uses the call stack. The next approach removes it entirely: once a level's next pointers are set, that level acts as a linked list we can walk to connect the level below.
This is the approach the follow-up is hinting at. Once all the next pointers on level k are connected, level k is a linked list. We can walk it using those next pointers and, as we go, connect every node on level k+1. No queue, no recursion, two pointers.
We start at the root (level 0) and move down. At each level we traverse left to right using the next pointers, wiring up the children below us. The same two connections apply: same-parent (left child to right child) and cross-parent (right child to the next node's left child).
We process levels strictly top-down. Level 1's next pointers are set while we traverse level 0, level 2's while we traverse level 1, and so on. So by the time we walk level k to connect level k+1, level k's pointers are already in place. The root needs no next because it is alone on level 0.
This relies on the tree being perfect. Every internal node has both children, so leftmost.left reliably tells us whether another level exists, and current.next.left always exists when current.next does. A general binary tree would need extra handling for missing children.
leftmost at the root. This tracks the leftmost node of the current level.leftmost.left is not null (there is a next level to connect):current = leftmost to traverse the current level.current is not null:current.left.next = current.right.current.next exists, current.right.next = current.next.left.current = current.next.leftmost down to the next level: leftmost = leftmost.left.Loading animation...
leftmost and current). No queue, no recursion stack. This satisfies the follow-up constraint.