Invert a Binary Tree is a tiny problem with a famous backstory — and it is the cleanest possible introduction to tree recursion. The whole solution is three meaningful lines.
Problem. Given the root of a binary tree, invert it (mirror it left-to-right) and return the
root. Inverting means: at every node, swap its left and right child.
Example: the tree with root 4, children 2 and 7, and leaves 1, 3, 6, 9 becomes the tree with
children 7 and 2 and leaves 9, 6, 3, 1 — the bottom row reversed.
The slow way first
You might reach for something elaborate — copy the tree, walk it with explicit coordinates, rebuild it flipped. But there is no shortcut needed and nothing to optimize away: you must touch every node exactly once to swap its children, so any correct solution is already O(n). The only real question is how to express it cleanly. Recursion makes it almost trivial.
The idea: swap, then recurse
A binary tree is self-similar: each child is itself the root of a smaller binary tree. So define the job in terms of itself.
At the current node, do two things: swap its left and right child, then invert each child's subtree the same way. The base case is an empty node (None) — there is nothing to swap, so just return.
The beautiful part: because every node swaps its children, the swaps compound. The root's two whole subtrees trade sides, and inside each of those, the grandchildren trade sides too. The result is a full mirror.
Walk through it
Step through the animation. We start at the root 4 and swap its children: 2 and 7 slide past each other, dragging their entire subtrees along. Then we recurse into 7 and swap 6 ↔ 9, and into 2 and swap 1 ↔ 3. The leaves have no children, so they hit the base case and return. When every node has been visited, the bottom row reads 9, 6, 3, 1 — the original 1, 3, 6, 9 reversed.
Pseudocode
invert(node):
if node is empty:
return # base case — nothing to mirror
swap node.left and node.right
invert(node.left) # mirror the (now-swapped) left subtree
invert(node.right) # mirror the (now-swapped) right subtree
return nodeThe Python solution
def invert_tree(root):
if root is None:
return None
root.left, root.right = root.right, root.left
invert_tree(root.left)
invert_tree(root.right)
return root- The
if root is Nonecheck is the base case — an empty subtree needs no work, so we return immediately. It is also what stops the recursion at the leaves. - Line 4 is the entire trick: Python tuple assignment swaps the two children in one step, no temp variable needed.
- The two
invert_tree(...)calls recurse into the children. Order does not matter — after the swap,root.leftis the former right child, and we mirror it too. - We
return rootso callers get the (now-inverted) tree back.
Complexity
| Case | Time | Notes |
|---|---|---|
| Every node | O(n) (moderate) | each node visited once, O(1) swap |
O(h) (moderate)Time is O(n) — you cannot do better, since every node's children must be swapped. The extra space is O(h) for the recursion call stack, where h is the tree's height: O(log n) for a balanced tree, but O(n) in the worst case (a degenerate, list-like tree).
When this pattern shows up
Most binary-tree problems are the same shape: do something at the current node, then recurse into both children, with the empty node as the base case. Tree height, node count, mirror-check, path sums, and "invert" all fit this mold. Get comfortable writing it and a whole category of problems opens up.
Do not forget the None base case. Without it, the recursion walks off the end of a leaf into a missing
child and crashes with an attribute error. Every recursive tree function needs that guard at the top.
Practice
After fully inverting the example tree, reading the bottom (leaf) row left-to-right, what sequence do you get?
1. What is the base case of the recursion?
2. Why is the time complexity O(n)?
3. What does the line root.left, root.right = root.right, root.left do?
4. What causes the O(h) extra space?