Description
Given the root of a binary tree, check whether it is a mirror of itself (i.e., symmetric around its center).
Example 1:

Input: root = [1,2,2,3,4,4,3]
Output: true
Example 2:

Input: root = [1,2,2,null,3,null,3]
Output: false
Constraints:
- The number of nodes in the tree is in the range
[1, 1000]. -100 <= Node.val <= 100
Follow up: Could you solve it both recursively and iteratively?
Approach 1: Recursive DFS ( Time, Space)
Intuition
A binary tree is symmetric if its left and right subtrees are mirror images of each other. Two subtrees and are mirrors if:
- Their root values are equal (
t1.val == t2.val). - ’s left child is a mirror of ‘s right child (
t1.leftvst2.right). - ’s right child is a mirror of ‘s left child (
t1.rightvst2.left).
class Solution {
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
return isMirror(root.left, root.right);
}
private boolean isMirror(TreeNode t1, TreeNode t2) {
// Base cases
if (t1 == null && t2 == null) return true;
if (t1 == null || t2 == null || t1.val != t2.val) return false;
// Compare outer pair (t1.left, t2.right) and inner pair (t1.right, t2.left)
return isMirror(t1.left, t2.right) && isMirror(t1.right, t2.left);
}
}
Complexity
- Time Complexity: — We visit every node in the binary tree at most once.
- Space Complexity: — Bounded by the height of the recursion stack ( for a balanced tree, for a skewed tree).
Approach 2: Iterative BFS ( Time, Space)
Intuition
Simulate the mirror check iteratively using a Queue (LinkedList handles null values cleanly):
- Offer
root.leftandroot.rightas the initial pair into the queue. - In each iteration, poll two nodes
t1andt2:- If both are
null, continue. - If one is
nullort1.val != t2.val, returnfalse.
- If both are
- Push corresponding mirror pairs side-by-side:
- Outer pair:
t1.leftandt2.right - Inner pair:
t1.rightandt2.left
- Outer pair:
import java.util.LinkedList;
import java.util.Queue;
class Solution {
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
// LinkedList allows null elements required for structural checks
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root.left);
queue.offer(root.right);
while (!queue.isEmpty()) {
TreeNode t1 = queue.poll();
TreeNode t2 = queue.poll();
if (t1 == null && t2 == null) continue;
if (t1 == null || t2 == null || t1.val != t2.val) return false;
// Enqueue outer children together
queue.offer(t1.left);
queue.offer(t2.right);
// Enqueue inner children together
queue.offer(t1.right);
queue.offer(t2.left);
}
return true;
}
}
Complexity
- Time Complexity: — Each node is enqueued and polled once.
- Space Complexity: — Queue holds at most one level of nodes at a time (up to nodes).
Easy Memory Rule
“Compare outer children together (
t1.left&t2.right) and inner children together (t1.right&t2.left)!”