Flatten Binary Tree to Linked List

MediumTrees · DFS · Morris-style Threading🧩 Tree DFSLeetCode #114 ↗Updated

Problem

Rearrange a binary tree in place into a single chain: every node's left pointer becomes null and its right pointer points to the next node. The chain must list the nodes in the tree's pre-order (node, then left subtree, then right subtree). Return nothing; modify root directly.
Inputroot = [4,2,6,1,3]Output[4,null,2,null,1,null,3,null,6]
Inputroot = [7,null,8]Output[7,null,8]
Inputroot = []Output[]

0 ≤ nodes ≤ 2000  ·  -100 ≤ Node.val ≤ 100  ·  Follow-up: O(1) extra space.

Try it yourself

Java
class Solution {
    public void flatten(TreeNode root) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
In pre-order, the node right after a whole left subtree is the current node's right child. So splice: find the last node of the left subtree (its rightmost node), hang cur.right there, move the left subtree to the right, and step forward — no stack or recursion needed.
PatternTree DFS

Instinct If the answer for a node can be built from the answers of its left and right subtrees, write one recursive function and trust it on the children.

Memory hack Ask the kids, then decide - each child reports up, the parent combines, and a global variable keeps the best "bend" seen so far.

Open the Tree DFS guide →

Approaches

Brute ForcePre-order List, then Relink

Time O(n)Space O(n)

Record all nodes in pre-order into a list, then walk the list and set left = null and right = next node for each one. The links are rewritten only after the traversal, so nothing is lost while reading.

Java
public void flatten(TreeNode root) {
    List<TreeNode> order = new ArrayList<>();
    preorder(root, order);
    for (int i = 0; i < order.size(); i++) {
        TreeNode node = order.get(i);
        node.left = null;
        node.right = i + 1 < order.size() ? order.get(i + 1) : null;
    }
}
private void preorder(TreeNode node, List<TreeNode> order) {
    if (node == null) return;
    order.add(node);
    preorder(node.left, order);
    preorder(node.right, order);
}

Simple and safe, but stores every node — fails the O(1)-space follow-up.

At a glance

LevelApproachTimeSpace
Brute ForcePre-order List, then RelinkO(n)O(n)
BetterReverse Pre-order with a prev PointerO(n)O(h)
OptimalIterative Splicing (Morris-style)O(n)O(1)
Common pitfalls
  • Forgetting to set left = null — the result must be a pure right-chain.
  • Overwriting cur.right before saving it; the old right subtree is lost.
  • In the recursive version, processing left before right breaks the reverse-pre-order invariant.
Interview tips
  • Start with the list approach, then ask whether O(1) extra space is required.
  • Explain the splice with a 3-node picture: left subtree goes between cur and its old right.
  • Argue the O(n) bound: each edge is walked by the rightmost search at most once.
Pattern
In-place tree rewiring (Morris-style threading) → when a traversal order must be materialised into pointers without extra memory.
My notes saved in this browser