Symmetric Tree
Given the root of a binary tree, return true if the tree is a mirror image of itself around its centre line — that is, if its left subtree and right subtree are reflections of one another in both shape and values. A tree with only a root is symmetric, and so is an empty tree.
- The number of nodes in the tree is in the range [1, 1000]
- -100 <= Node.val <= 100
- Both shape and values must mirror
- A single node is symmetric
root = [1,2,2,3,4,4,3]trueroot = [1,2,2,null,3,null,3]falseroot = [1,2,2,2,null,2]falseroot = [1]trueSymmetry is not a statement about the tree as a whole, it is a statement about its two halves: the left subtree must be the mirror image of the right subtree. So the question becomes a comparison between two trees, and we already have the machinery for that from Same Tree.
The only thing that changes is what corresponds to what.
Hold a tree up to a mirror. The leftmost node of the real tree appears at the far right of the reflection. So when comparing a node a from the left subtree with its counterpart b from the right subtree, their children do not pair up left-with-left. They pair up crossed:
a.left faces b.right — these are the outer pair, the two positions furthest from the centre line.a.right faces b.left — the inner pair, the two closest to the centre.That is the entire modification. The Same Tree recursion compared (p.left, q.left) and (p.right, q.right); here the calls become (a.left, b.right) and (a.right, b.left). Everything else — both-null true, one-null false, values-differ false — is unchanged, because "reflects" and "equals" have exactly the same failure modes at a single position.
def isSymmetric(root):
if root is None:
return True
return mirrors(root.left, root.right) # the two halves, compared against each other
def mirrors(a, b):
if a is None and b is None:
return True # both sides stop here — still symmetric
if a is None or b is None:
return False # one stops, one does not
if a.val != b.val:
return False
return mirrors(a.left, b.right) and mirrors(a.right, b.left) # crossedThe second trap is checking values level by level and asking whether each level reads as a palindrome. The third example kills that idea — the level holds 2, 2 on both sides and reads identically forwards and backwards, yet the two nodes hang on the wrong sides of their parents. Symmetry is about matched positions, and only the crossed pairing tracks positions correctly.
Now the failing case, root 1 with children 2 and 2, where each 2 has only a right child holding 3. Compare the 2s: values match. Outer pair: left-2's left is null, right-2's right is 3 — exactly one is null, so false. Correct: for a mirror, the left 2's child would have to appear on the opposite side from the right 2's child, and both are on the right.
Each node is examined at most once as part of exactly one pair, so the time is O(N) and the space is O(H) for the recursion. An iterative version pushes node pairs onto a stack, or walks level by level with a queue enqueuing children in crossed order — useful if the tree may be deep.
The point worth extracting is how small the edit was. Same Tree and Symmetric Tree are the same algorithm with a different pairing rule, and that suggests a habit: when a new problem compares two structures, ask what the correspondence is, and plug it into the paired-recursion skeleton rather than starting over. Same-position gives equality; crossed gives mirroring; comparing a tree against every subtree of another gives subtree-containment. The skeleton — both-empty, one-empty, local check, paired recursive calls — is fixed. Only the pairing changes.
Symmetric Tree Check
Mirror Geometry Verification
"Mirror Check: Compare Opposite Sides."
Strategy
A tree is symmetric if it is a mirror image. compare opposite subtrees recursively.
"Is symmetry preserved?"