Problem Overview
You are given the root of a binary tree. The task is to invert the binary tree and return its root.
Inverting a binary tree means swapping the left and right child of every node in the tree.
Example 1
Input:
4
/ \
2 7
/ \ / \
1 3 6 9
Output:
4
/ \
7 2
/ \ / \
9 6 3 1
Explanation:
Every left child is swapped with its corresponding right child recursively throughout the entire tree.
Example 2
Input: root = [2,1,3] Output: [2,3,1]
Example 3
Input: root = [] Output: []
Intuition / Approach
The problem can be understood visually — at each node in the binary tree, we swap its left and right children. Then we repeat the same process for the left and right subtrees.
There are multiple ways to perform this inversion:
- Recursive (Depth-First Search) approach.
- Iterative (Breadth-First Search) approach using a queue.
The recursive approach is the most intuitive and elegant because it mirrors the tree’s structure directly.
Algorithm Explanation (Recursive Approach)
We define a recursive function invertTree(root) that:
- Returns
nullif the current node (root) isnull. - Swaps the left and right child nodes.
- Recursively inverts the left and right subtrees.
- Returns the root node after the swap.
Step-by-step explanation:
- Base Case:
If the node isnull, there’s nothing to invert, so we simply returnnull. - Swap Operation:
Swaproot.leftandroot.right. - Recursive Calls:
Call the same function on bothroot.leftandroot.rightto invert their subtrees. - Return Result:
Return the modifiedrootnode.
Java Code Implementation (Recursive Approach)
// Definition for a binary tree node
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int val) {
this.val = val;
}
}
public class InvertBinaryTree {
public TreeNode invertTree(TreeNode root) {
// Base case: if the node is null, nothing to invert
if (root == null) {
return null;
}
// Swap the left and right children
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
// Recursively invert the left and right subtrees
invertTree(root.left);
invertTree(root.right);
// Return the root after inversion
return root;
}
// Example usage
public static void main(String[] args) {
InvertBinaryTree tree = new InvertBinaryTree();
// Construct sample binary tree
TreeNode root = new TreeNode(4);
root.left = new TreeNode(2);
root.right = new TreeNode(7);
root.left.left = new TreeNode(1);
root.left.right = new TreeNode(3);
root.right.left = new TreeNode(6);
root.right.right = new TreeNode(9);
TreeNode invertedRoot = tree.invertTree(root);
tree.printTree(invertedRoot); // Optional method to visualize result
}
// Helper method to print tree in-order
private void printTree(TreeNode root) {
if (root == null) return;
printTree(root.left);
System.out.print(root.val + " ");
printTree(root.right);
}
}
Complexity Analysis
- Time Complexity:O(n)
- Every node in the binary tree is visited exactly once.
- Swapping children takes constant time per node.
- Hence, total time complexity = O(n), where n is the number of nodes.
- Space Complexity:O(h)
- The recursion depth depends on the height of the binary tree (
h). - In the worst case (skewed tree), recursion depth can be
O(n). - In the best case (balanced tree), depth is
O(log n).
- The recursion depth depends on the height of the binary tree (
Alternative Approach (Iterative using Queue)
If you want to avoid recursion (for example, to prevent stack overflow in deep trees), you can use an iterative level-order traversal using a queue.
At each step:
- Dequeue a node from the queue.
- Swap its left and right children.
- Enqueue the non-null children for further processing.
Java Implementation:
import java.util.LinkedList;
import java.util.Queue;
public class InvertBinaryTreeIterative {
public TreeNode invertTree(TreeNode root) {
if (root == null) {
return null;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
TreeNode current = queue.poll();
// Swap the children
TreeNode temp = current.left;
current.left = current.right;
current.right = temp;
// Add children to the queue if not null
if (current.left != null) {
queue.add(current.left);
}
if (current.right != null) {
queue.add(current.right);
}
}
return root;
}
}
Comparison Between Recursive and Iterative Approaches
| Criteria | Recursive Approach | Iterative Approach |
|---|---|---|
| Ease of Implementation | Easier and cleaner | Slightly more code |
| Space Usage | O(h) (due to recursion) | O(n) (due to queue) |
| Performance | O(n) time | O(n) time |
| Best for | Balanced trees | Deep or skewed trees |
