Mirror a Binary Tree in DSA Typescript - Time & Space Complexity
We want to understand how long it takes to flip a binary tree so that left and right children swap places.
How does the time needed grow as the tree gets bigger?
Analyze the time complexity of the following code snippet.
function mirrorTree(root: TreeNode | null): TreeNode | null {
if (root === null) return null;
const left = mirrorTree(root.left);
const right = mirrorTree(root.right);
root.left = right;
root.right = left;
return root;
}
This code flips the tree by swapping left and right children for every node recursively.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive calls visiting each node once.
- How many times: Once per node in the tree.
Each node is visited once to swap its children, so the work grows directly with the number of nodes.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 swaps |
| 100 | About 100 swaps |
| 1000 | About 1000 swaps |
Pattern observation: The time grows linearly as the tree size increases.
Time Complexity: O(n)
This means the time to mirror the tree grows in direct proportion to the number of nodes.
[X] Wrong: "The time complexity is O(log n) because the tree height matters most."
[OK] Correct: Even though the tree height affects recursion depth, every node must be visited once, so the total work depends on all nodes, not just height.
Understanding this helps you explain how recursive tree algorithms work and how their time depends on node count, a key skill in many coding challenges.
"What if we changed the tree to a linked list (all nodes have only one child)? How would the time complexity change?"
Practice
Solution
Step 1: Understand the mirror operation
Mirroring a binary tree means swapping the left and right children of every node.Step 2: Effect on the tree structure
This operation flips the tree around its center, creating a mirror image.Final Answer:
Swap the left and right children of every node in the tree -> Option AQuick Check:
Mirror = Swap children [OK]
- Thinking mirror means sorting nodes
- Confusing mirror with removing nodes
- Assuming mirror changes node values
Solution
Step 1: Identify the input and output types
The function should accept a TreeNode or null and return a TreeNode or null after mirroring.Step 2: Check each option's signature
function mirrorTree(root: TreeNode | null): TreeNode | null matches the expected input and output types for a binary tree mirror function.Final Answer:
function mirrorTree(root: TreeNode | null): TreeNode | null -> Option DQuick Check:
Correct signature uses TreeNode or null [OK]
- Using primitive types like number or string instead of TreeNode
- Returning void instead of the mirrored tree
- Not allowing null as input
class TreeNode {
val: number;
left: TreeNode | null;
right: TreeNode | null;
constructor(val: number, left: TreeNode | null = null, right: TreeNode | null = null) {
this.val = val;
this.left = left;
this.right = right;
}
}
function mirrorTree(root: TreeNode | null): TreeNode | null {
if (!root) return null;
const left = mirrorTree(root.left);
const right = mirrorTree(root.right);
root.left = right;
root.right = left;
return root;
}
function preorder(root: TreeNode | null): number[] {
if (!root) return [];
return [root.val, ...preorder(root.left), ...preorder(root.right)];
}
const tree = new TreeNode(1, new TreeNode(2, new TreeNode(4), new TreeNode(5)), new TreeNode(3));
const mirrored = mirrorTree(tree);
console.log(preorder(mirrored));Solution
Step 1: Understand the original tree structure
The tree is:
1
āā 2
ā āā 4
ā āā 5
āā 3Step 2: Mirror the tree by swapping left and right children
After mirroring:
1
āā 3
āā 2
āā 5
āā 4Step 3: Preorder traversal of mirrored tree
Preorder visits root, left, right:
1, 3, 2, 5, 4Final Answer:
[1, 3, 2, 5, 4] -> Option BQuick Check:
Mirror preorder = [1, 3, 2, 5, 4] [OK]
- Not swapping children correctly
- Confusing preorder with inorder or postorder
- Forgetting to mirror recursively
function mirrorTree(root: TreeNode | null): TreeNode | null {
if (!root) return null;
mirrorTree(root.left);
mirrorTree(root.right);
const temp = root.left;
root.left = root.right;
root.right = temp;
return root;
}Solution
Step 1: Analyze the recursive calls
The function calls mirrorTree on root.left and root.right but does not assign the results back to root.left and root.right.Step 2: Understand the effect of missing assignments
Without assigning, the subtrees are not updated with their mirrored versions, so the mirror is incomplete.Final Answer:
The recursive calls do not assign the mirrored subtrees back to root.left and root.right -> Option CQuick Check:
Assign recursive results to children [OK]
- Ignoring return values of recursive calls
- Swapping children before recursion
- Incorrect base case handling
Solution
Step 1: Understand mirroring effect on single-child nodes
Mirroring swaps left and right children of every node.Step 2: Effect on nodes with only one child
If a node has only a left child, after mirroring, that child becomes the right child, and left becomes null.Final Answer:
Nodes with only left child will have only right child after mirroring -> Option AQuick Check:
Mirror swaps children, single left child becomes right [OK]
- Assuming children disappear after mirroring
- Thinking mirroring adds children
- Believing tree structure stays same
Ready to prove it?
Pass the test and this pattern moves unknown
