The problem
You get the root of a binary tree. Invert it, meaning produce its mirror image, where every node’s left and right children are swapped. Return the root.
Input: Output:
4 4
/ \ / \
2 7 7 2
/ \ / \ / \ / \
1 3 6 9 9 6 3 1
Level order: [4,2,7,1,3,6,9] -> [4,7,2,9,6,3,1]Every level reads right-to-left after the inversion.
How to think about it
Start with brute force. You might think level by level: read each level, reverse it, and rebuild the tree. That needs extra storage, and rebuilding the links correctly is fiddly. It also misses how simple the real structure is.
The key insight: mirroring a tree means mirroring each subtree and then swapping them. If you invert the right subtree and hang it on the left, and invert the left subtree and hang it on the right, the whole tree is mirrored. So at every node, swap the two (already inverted) children. That’s it.
The order doesn’t matter much. You can swap first and then recurse (preorder), or recurse first and swap on the way back up (postorder). Both touch every node once. Python’s tuple assignment lets you do the recursion and the swap in one line, because the right-hand side is fully evaluated before either assignment happens.
Which pattern is this? Tree DFS. The tell is “do the same thing to every node, and the result for a tree is built from the results for its subtrees”.
Approach
- If the node is empty, return
None. - Invert the right subtree and the left subtree recursively.
- Attach the inverted right subtree as the new left child, and the inverted left as the new right.
- Return the node.
Solution
def invert_tree(root):
if not root: return None
root.left, root.right = invert_tree(root.right), invert_tree(root.left) # RHS evaluated first, then swapped in
return root
# invert(tree[4,2,7,1,3,6,9]) level-order -> [[4],[7,2],[9,6,3,1]]Dry run
On the example. Each node finishes after both its subtrees, so this is the order the swaps complete in:
| Node finished | New left | New right |
|---|---|---|
| 9 | None | None |
| 6 | None | None |
| 7 | 9 | 6 |
| 3 | None | None |
| 1 | None | None |
| 2 | 3 | 1 |
| 4 | 7 | 2 |
Reading the result level by level gives [[4], [7, 2], [9, 6, 3, 1]].
Complexity
- Time: O(n). Every node is visited once and does one swap.
- Space: O(h). The recursion stack goes as deep as the tree height h: O(log n) balanced, O(n) skewed. The tree is changed in place, so no other memory is used.
Edge cases and pitfalls
- Empty tree returns
None. - Single node returns itself unchanged.
- Swapping in two lines without a temp is a classic bug:
root.left = invert(root.right)followed byroot.right = invert(root.left)inverts the new left, which is the old right, twice. Use tuple assignment or a temporary variable. - Deep trees can exceed Python’s recursion limit. A BFS with a queue that swaps children at each node works just as well.
Related problems
- Same Tree (LeetCode 100): the same two-subtree recursion, returning a boolean.
- Maximum Depth of Binary Tree (LeetCode 104): the simplest recurse-combine-return example.
- Binary Tree Level Order Traversal (LeetCode 102): the BFS you’d use to print and check the inverted tree.
- 1.Maximum Depth of Binary Tree (LeetCode 104)
- 2.Same Tree (LeetCode 100)
- 3.Invert Binary Tree (LeetCode 226)
- 4.Path Sum (LeetCode 112)
- 5.Subtree of Another Tree (LeetCode 572)
- 6.Diameter of Binary Tree (LeetCode 543)
- 7.Lowest Common Ancestor of a BST (LeetCode 235)
- 8.Lowest Common Ancestor of a Binary Tree (LeetCode 236)
- 9.Validate Binary Search Tree (LeetCode 98)
- 10.Kth Smallest Element in a BST (LeetCode 230)
- 11.Construct Binary Tree from Preorder and Inorder (LeetCode 105)
- 12.Serialize and Deserialize Binary Tree (LeetCode 297)
- 13.Binary Tree Maximum Path Sum (LeetCode 124)