150NeetCode 150

50.Same Tree

EasyBlind 75Trees ยท 5/15

Problem

Given the roots of two binary trees p and q, return true if they are the same tree: structurally identical, with equal values in every corresponding node. Otherwise return false.

Examples

Input:  p = [1,2,3], q = [1,2,3]
Output: true
Input:  p = [1,2], q = [1,null,2]
Output: false
Explanation: Same values, but 2 is a left child in p and a right child in q.
Input:  p = [1,2,1], q = [1,1,2]
Output: false
Explanation: Same shape, but the children's values are swapped.

Constraints

  • The number of nodes in both trees is in the range [0, 100].
  • -10^4 <= Node.val <= 10^4

๐Ÿ’ก Key Insight

Two trees are equal exactly when their roots match and their left subtrees are equal and their right subtrees are equal. Walk both trees in lock-step and compare node pairs; the first mismatch (one node null and the other not, or different values) proves they differ.

Serialize and Compare

TimeO(n + m)SpaceO(n + m)

Intuition

If we write each tree as a string that captures both values and structure, equal trees produce equal strings. A pre-order traversal that also records null children (e.g. as #) uniquely identifies a binary tree, so comparing the two strings answers the question.

Algorithm

  1. Serialize p with pre-order DFS, appending each value followed by a comma and #, for every null.
  2. Serialize q the same way.
  3. Return whether the two strings are equal.

Visualization

p = [1,2]       -> "1,2,#,#,#,"
q = [1,null,2]  -> "1,#,2,#,#,"
strings differ at position 2 -> false

Code

java
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        StringBuilder a = new StringBuilder();
        StringBuilder b = new StringBuilder();
        serialize(p, a);
        serialize(q, b);
        return a.toString().equals(b.toString());
    }

    // pre-order with explicit null markers encodes structure as well as values
    private void serialize(TreeNode node, StringBuilder sb) {
        if (node == null) {
            sb.append("#,");
            return;
        }
        sb.append(node.val).append(',');
        serialize(node.left, sb);
        serialize(node.right, sb);
    }
}

Complexity

  • Time: O(n + m) โ€” both trees are fully serialized, even if they differ at the root.
  • Space: O(n + m) โ€” the two strings.

Complexity Comparison

Approach Time Space
Serialize and Compare O(n + m) O(n + m)
Iterative BFS on Node Pairs O(min(n, m)) O(min(n, m))
Recursive DFS O(min(n, m)) O(min(h1, h2))

Common Pitfalls

  • Comparing only traversal values without null markers โ€” [1,2] and [1,null,2] produce the same pre-order 1,2 but are different trees.
  • Checking p.val != q.val before the null checks, which throws a NullPointerException.
  • Using ArrayDeque to store null children โ€” it rejects null elements; wrap pairs in an array or use LinkedList.
  • Comparing nodes with p == q (reference equality) โ€” the trees are separate objects, so you must compare val.