You are given a perfect binary tree where all leaves are on the same level, and every parent has two children. The binary tree has the following definition:

solutions
level-order traversal
This is the logical/simple way to do this. Just do level-order traversal, and then for each level, link adjacent nodes.
def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
if not root:
return root
q = deque([root])
def link_level():
i = 0
while i+1 < len(q):
q[i].next = q[i+1]
i += 1
while q:
level_len = len(q)
for _ in range(level_len):
cur = q.popleft()
if cur.left:
q.append(cur.left)
if cur.right:
q.append(cur.right)
link_level()
return rootiterative O(1)
Instead of keeping track of the whole level in a queue, we just treat each level as a sort of linked list, and link up a whole level before moving onto the next level.
There are two connections to consider:
- Linking a node’s left child to it’s right child (trivial).

- Linking a node’s right child to
node.next’s left child. Note that in this case, we just need to donode.right = node.next.left. If we can guarantee that all thenextpointers are set, this can be done safely.
So, we maintain a reference to the “head” of the current level, and traverse left to right, setting these two types of connections. Once we’re done, we can update leftmost and move onto the next level.
We only move on to the level when we are done establishing the next pointers for the level . Since we have access to all the nodes on a particular level via the next pointers, we can use these next pointers to establish the connections for the next level or the level containing their children.
def connect(self, root: "Node") -> "Node":
if not root:
return root
# Start with the root node. There are no next pointers
# that need to be set up on the first level
leftmost = root
# Once we reach the final level, we are done
# leftmost.left will be None once we reach leaves
while leftmost.left:
# Iterate the "linked list" starting from the head
# node and using the next pointers, establish the
# corresponding links for the next level
head = leftmost
while head:
# CONNECTION 1
head.left.next = head.right
# CONNECTION 2
if head.next:
head.right.next = head.next.left
# Progress along the list (nodes on the current level)
head = head.next
# Move onto the next level
leftmost = leftmost.left
return rootrecursion
The problem follow-up asks for a constant space solution.
W can recursively populate the next pointers of the current node’s children.
class Solution:
def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
if root:
if root.right:
if root.next:
root.right.next = root.next.left
self.connect(root.right)
if root.left:
root.left.next = root.right
self.connect(root.left)
return root