Flatten Binary Tree to Linked List – Solution & Complexity
Solution Walkthrough
1. Understand what the flattened tree should look like
- The final structure must follow preorder traversal: visit the current node, then its left subtree, then its right subtree.
- Every node's
leftpointer must becomenull. - Every node's
rightpointer should point to the next node in preorder order, so the tree becomes a single right-leaning chain.
2. Start with a simple preorder list approach
- Run a preorder traversal and store every visited node in an array.
- Then walk that array and relink each node so
left = nullandright = next node. - This is easy to reason about and correct, but it uses
O(n)extra space for the stored traversal.
3. Improve it by splicing subtrees in place
- A more space-efficient idea is to flatten the left and right subtrees first.
- Once both sides are already flattened, place the flattened left subtree between the current node and the flattened right subtree.
- In other words: save the original right subtree, move the left subtree to the right, null out
left, then connect the left subtree's tail to the saved right subtree.
4. Optimal recursive in-place solution
- Let a helper return the tail node of the flattened subtree rooted at the current node.
- Recursively flatten the left and right subtrees first.
- If a left subtree exists, splice it between the node and the original right subtree, then return the rightmost tail that now ends the flattened subtree.
5. Dry run on the classic example
Trace root = [1,2,5,3,4,null,6]:
- Flatten subtree rooted at
2. Its preorder is2,3,4, so that subtree becomes2 -> 3 -> 4. - Flatten subtree rooted at
5. Its preorder is5,6, so it becomes5 -> 6. - Return to
1. Save the original right subtree head5. - Move the flattened left subtree to
1.right, so now1 -> 2 -> 3 -> 4. - Connect the tail of that moved left chain (node
4) to the saved right subtree head5. - Final chain:
1 -> 2 -> 3 -> 4 -> 5 -> 6, serialized as[1,null,2,null,3,null,4,null,5,null,6].
6. Common mistakes
- Forgetting to save the original right subtree before overwriting
node.right. - Forgetting to set
node.left = null, which leaves stray left pointers and breaks the required output shape. - Returning
None/null/voidinstead of returning the mutatedroot. - Re-linking the current node before recursively flattening its children, which can lose part of the tree.
7. Edge cases to test mentally
- Empty tree: input
[]should return[]. - Single node: input
[1]stays[1]. - Already-flat right chain: the algorithm should preserve it.
- Left-only chain: every node shifts from
leftpointers torightpointers in the same preorder order.
8. Final full solution and complexity
Flatten each subtree with a postorder-style recursion that returns the tail of the flattened result. Each node is visited once, so time is O(n). The extra space is O(h) for the recursion stack, where h is the tree height.