Algorithm

Same Tree

Trees Pattern

Same Tree

Given the roots of two binary trees p and q, return true if they are identical: the same shape and the same value at every corresponding position. Two empty trees are identical. A tree is not identical to one that merely holds the same values in a different arrangement.

CONSTRAINTS
  • The number of nodes in each tree is in the range [0, 100]
  • -10⁴ <= Node.val <= 10⁴
  • Both structure and values must match
  • Either tree may be empty
EXAMPLE 1
Input: p = [1,2,3], q = [1,2,3]
Output: true
Same shape, same values in the same positions.
EXAMPLE 2
Input: p = [1,2], q = [1,null,2]
Output: false
Both trees hold the values 1 and 2, but in one the 2 is a left child and in the other a right child. Shape is part of identity, so this fails.
EXAMPLE 3
Input: p = [1,2,1], q = [1,1,2]
Output: false
Identical shapes and identical multisets of values, yet the values sit in swapped positions. Comparing sorted contents would wrongly pass this.
EXAMPLE 4
Input: p = [], q = []
Output: true
Two empty trees are the same tree. This is the base case the recursion rests on, not an exceptional input.
Does 'same' mean same values, same shape, or both?
Both, at every position. Two trees with the same values arranged differently are not the same.
What if both trees are empty?
True. And if exactly one is empty, false — that asymmetry is what the null checks encode.
Can I compare their traversals instead?
Only if the traversal includes null markers. A bare pre-order list is ambiguous about shape, as Serialize and Deserialize shows; with markers, comparing the two encodings does work, at the cost of building both strings.
Are the trees guaranteed to be the same size?
No. Different sizes are simply one way of being different, and the recursion detects it the moment one side runs out before the other.

Two trees are the same when a walk through both, taking the same turns, never finds a disagreement. That framing suggests the method immediately: instead of walking one tree, walk both at once, keeping a pointer in each and moving them in step.

One node pair, three questions

Give the recursion two arguments — a node from each tree, always at the same position — and ask what can be decided right there.

- Both are null. Both trees stop at this position in the same way. Nothing disagrees, so this pair is fine: true.
- Exactly one is null. One tree has a node here and the other does not. That is a difference in shape, and no amount of matching further down could repair it: false.
- Both exist but hold different values. A difference in content: false.
- Both exist and match. This position is fine, but that says nothing about what lies below. The trees are the same here only if their left sides agree and their right sides agree — two smaller instances of the identical question.
python
def isSame(p, q):
    if p is None and q is None:
        return True                      # both stop here, in the same way
    if p is None or q is None:
        return False                     # one stops, one does not — a shape difference
    if p.val != q.val:
        return False                     # a value difference
    return isSame(p.left, q.left) and isSame(p.right, q.right)
Crucial Notethe order of the two null tests matters. both null must be checked before either null, because the second condition is also true when both are null and would wrongly report false. Written in this order, reaching the third line guarantees that both nodes exist, so p.val is safe to read — a null check that also acts as a guard against dereferencing. This ordered-guard shape appears in nearly every paired tree recursion, and the two-null case first is the invariant that makes it safe.

Also note that the null case is not an afterthought here — the absence of a node is itself information being compared. That is the same realisation as in Serialize and Deserialize: the gaps carry shape, and a comparison that ignores them cannot tell [1,2] from [1,null,2].

Why the lock-step walk is enough

It is worth convincing yourself this really settles the question. If the trees are identical, then at every reachable position both pointers hold matching nodes, no test ever fires, and every branch bottoms out at a pair of nulls returning true — so the answer is true. If they differ, there is some position where they first disagree, either in a value or in whether a node exists; the paired walk reaches that position by taking the same turns in both trees, and the corresponding test fires. Neither direction leaves a gap, so the walk is exactly as strong as the definition.

The and also short-circuits: as soon as the left sides disagree, the right sides are never examined, and the false travels straight up to the root without further work.

Worked example:p = [1,2,1] and q = [1,1,2]
- Compare the roots: both exist, both are 1. Proceed to the children.
- Left pair: p's left is 2, q's left is 1. Both exist, values differ — false.
- That false collapses the and at the root immediately. The right pair is never compared at all, even though those nodes (1 and 2) would also have disagreed.
- Answer: false.

Now the second example, p = [1,2] against q = [1,null,2]. Roots match. Left pair: p's left is 2, q's left is null — exactly one is null, so false. The trees hold the same values, but the shape check catches the difference before any value is even read.

Cost, and the shape to reuse

In the worst case every position is compared once, so the time is O(min(N, M)) — the walk stops as soon as one tree runs out — and in practice often far less thanks to short-circuiting. Space is the recursion stack, O(H).

What generalises is the paired recursion itself: when a question is about two structures rather than one, recurse on both together and decide, at each pair, whether a local disagreement settles it. The template has three parts — a both-empty case, an exactly-one-empty case, and a local comparison followed by paired recursive calls — and only the last part changes between problems. Symmetric Tree, coming next, is this exact function with one small change: instead of pairing left with left, it pairs left with right, which turns "are these two trees equal?" into "are these two trees mirror images?"

Interactive Strategy Visualization

Same Tree Audit

Parallel Structure Verification

123123
Scanning Topology...
Lockstep Analysis

Checking root values. Both are 1.

"Both Null? True. Diff Vals? False."

Strategy

Parallel traversal ensures structural equality. catch differences immediately.

"Base-case focused recursion."

O(N) Time · O(N) Space Serialize Both And Compare
O(min(N,M)) Time · O(H) Space Paired Lock-step Walk