Algorithm

Flatten Binary Tree

Trees Pattern

Flatten Binary Tree to Linked List

Rearrange the tree in place into a chain that leans entirely to the right: every node's left pointer must end up null, and its right pointer must point to the next node in the tree's original pre-order sequence. The last node's right is null. You must reuse the existing nodes and rewire their pointers rather than allocating new ones, and the same root object is the head of the resulting chain. An empty tree stays empty.

CONSTRAINTS
  • The number of nodes in the tree is in the range [0, 2000]
  • -100 <= Node.val <= 100
  • The transformation must be in place — no new nodes
  • Every left pointer must be null when you finish
EXAMPLE 1
Input: root = [1,2,5,3,4,null,6]
Output: 1 → 2 → 3 → 4 → 5 → 6, all via right pointers, all left pointers null
The tree's pre-order sequence is 1, 2, 3, 4, 5, 6, and that is exactly the order along the chain. Note that 5, originally the root's right child, ends up after 3 and 4, which came from the other side of the tree.
EXAMPLE 2
Input: root = [1,null,2,null,3]
Output: 1 → 2 → 3
A tree that already leans right is already in pre-order chain form, so nothing moves. It is still worth stepping through, since a solution that blindly rewires can easily break this case.
EXAMPLE 3
Input: root = [1,2,null,3]
Output: 1 → 2 → 3
A pure left chain becomes a pure right chain of the same order — every node shifts from the left pointer to the right pointer of its parent.
EXAMPLE 4
Input: root = []
Output: []
There is nothing to rewire, and null is returned unchanged rather than treated as an error.
Do I need to create new nodes?
No — rewire the existing ones. Building a fresh right-leaning chain of copies would produce the right shape but violates the in-place requirement, and interviewers ask about this specifically.
Must every left pointer be set to null?
Yes. Leaving old left pointers in place would give nodes two outgoing links, so the result would not be a list at all.
Which traversal order defines the chain?
Pre-order, so the root comes first and the entire original left subtree precedes the original right subtree.
Is O(1) extra space required?
Usually not, but it is the natural follow-up. Recursion costs O(H) stack space; there is a Morris-flavoured rewiring that avoids it entirely.

Flatten means rewire the tree, in place, into one right-leaning chain. The order along the chain is the tree's pre-order: node, then its whole left subtree, then its whole right subtree. Every left pointer ends up null.

text
      1
     / \
    7   9           pre-order walk: 1 7 3 4 9 2
   / \   \
  3   4   2

  becomes:   1 -> 7 -> 3 -> 4 -> 9 -> 2      (all along right pointers)
The greedy top-down order self-destructs

Tempting first move: at each node, swing the left subtree over to the right pointer.

text
     1          node.right = node.left
    / \        node.left  = None
   7   9

But node.right = node.left overwrites the only link to 9 and everything beneath it — that whole subtree just vanishes. A node's own rewrite clobbers a pointer the recursion still needs. Lesson: never overwrite a link until you're done reading what it points to.

Build the chain from its tail

The crash happened because we linked a node forward before we were done with its old pointers. So flip it around: build the chain starting from its last node, working backward to the root.

Here's why that fixes everything. To give a node its new right pointer, the node that comes after it in the chain must already exist — then we just point at it. If we always handle nodes in reverse chain order, that successor is already built and parked in a variable tail. Every write is "point at something already finished," so we never clobber a pointer we still need.

text
suppose the tail end is already linked:   9 -> 2      (tail = 9)
now handle 4:  point 4's right at tail  -> 4 -> 9 -> 2   (tail = 4)
now handle 3:                            -> 3 -> 4 -> 9 -> 2   (tail = 3)

And reverse chain order is easy to produce, because the chain order is pre-order (node, left, right). Reverse it and you get right, left, node: walk the right subtree first, then the left, do the node last. Each node then just points right at tail, nulls its left, and becomes the new tail.

text
visit order (reverse pre-order):  2  9  4  3  7  1

 2                         tail = 2
 9 -> 2                    tail = 9
 4 -> 9 -> 2               tail = 4
 3 -> 4 -> 9 -> 2          tail = 3
 7 -> 3 -> 4 -> 9 -> 2     tail = 7
 1 -> 7 -> 3 -> 4 -> 9 -> 2    done
python
tail = None

def flatten(node):
    nonlocal tail
    if node is None:
        return
    flatten(node.right)      # far end of the chain, built first
    flatten(node.left)
    node.right = tail        # link forward to the already-built part
    node.left = None
    tail = node              # this node is now the front

The whole trick is one ordering: flatten(node.right) reads the right pointer on the first line, while it's still intact; node.right = tail writes it only after both subtrees are fully handled and don't need their old links. Move that write above the calls and you're back to the self-destructing version.

O(N) time — each node written once — and O(H) stack. (An O(1)-space variant threads the tree iteratively: for each node with a left child, splice its right subtree onto the left subtree's rightmost node, move the left subtree over to the right, and step right.)

Interactive Strategy Visualization

In-Place Flattening

Reverse Pre-Order Stitching

123456
Starting Reverse Pre-order: Right → Left → Root.
Pointer Re-Assignment
Stage
Initialize
Current Prev Reference
Node null

"To flatten without extra space, process from tail to head."

Strategy

A reverse pre-order (Right → Left → Root) visits nodes in the exact opposite order they appear in the flattened list. This allows us to point `node.right` to the `prev` node easily.

"Right → Left → Root"

O(N²) Splice At Each Tail
O(N) Time · O(H) Space Reverse Pre-order Threading
O(N) Time · O(1) Space Morris-style Rewiring