100. Same Tree - Explanation
Description
Given the roots of two binary trees p and q, return true if the trees are equivalent, otherwise return false.
Two binary trees are considered equivalent if they share the exact same structure and the nodes have the same values.
Example 1:
Input: p = [1,2,3], q = [1,2,3]
Output: trueExample 2:
Input: p = [4,7], q = [4,null,7]
Output: falseExample 3:
Input: p = [1,2,3], q = [1,3,2]
Output: falseConstraints:
0 <= The number of nodes in both trees <= 100.-100 <= Node.val <= 100
Topics
Recommended Time & Space Complexity
You should aim for a solution with O(n) time and O(n) space, where n is the number of nodes in the tree.
Hint 1
Can you think of an algorithm that is used to traverse the tree? Maybe in terms of recursion.
Hint 2
We can use the Depth First Search (DFS) algorithm to traverse the tree. Can you think of a way to simultaneously traverse both the trees?
Hint 3
We traverse both trees starting from their root nodes. At each step in the recursion, we check if the current nodes in both trees are either null or have the same value. If one node is null while the other is not, or if their values differ, we return false. If the values match, we recursively check their left and right subtrees. If any recursive call returns false, the result for the current recursive call is false.
Prerequisites
Before attempting this problem, you should be comfortable with:
- Binary tree structure - Understanding nodes with left/right children and null references
- Tree traversal (DFS) - Recursively visiting nodes in a binary tree
- Recursion - Using recursive function calls to process tree structures
- Base case handling - Properly handling null nodes as termination conditions
1. Depth First Search
Intuition
Two binary trees are the same if:
- Their structure is identical.
- Their corresponding nodes have the same values.
So at every position:
- If both nodes are
null→ they match. - If one is
nullbut the other isn't → mismatch. - If both exist but values differ → mismatch.
- Otherwise, compare their left subtrees and right subtrees recursively.
This is a direct structural + value-based DFS comparison.
Algorithm
- If both
pandqarenull, returntrue. - If only one is
null, returnfalse. - If their values differ, return
false. - Recursively compare:
p.leftwithq.leftp.rightwithq.right
- Return
trueonly if both subtree comparisons aretrue.
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
if not p and not q:
return True
if p and q and p.val == q.val:
return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
else:
return FalseTime & Space Complexity
- Time complexity:
- Space complexity:
- Best Case (balanced tree):
- Worst Case (degenerate tree):
Where is the number of nodes in the tree and is the height of the tree.
2. Iterative DFS
Intuition
Instead of using recursion, we can use an explicit stack to compare the two trees.
Each stack entry contains a pair of nodes—one from each tree—that should match.
For every pair:
- If both are
null, they match → continue. - If only one is
null, or their values differ → trees are not the same. - If they match, push their children in the same order:
- Left child pair
- Right child pair
If we finish processing all pairs with no mismatch, the trees are identical.
Algorithm
- Initialize a stack with the pair
(p, q). - While the stack is not empty:
- Pop a pair
(node1, node2). - If both are
null, continue. - If exactly one is
null, returnfalse. - If
node1.val != node2.val, returnfalse. - Push:
(node1.left, node2.left)(node1.right, node2.right)
- Pop a pair
- After the loop finishes, return
true(all nodes matched).
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
stack = [(p, q)]
while stack:
node1, node2 = stack.pop()
if not node1 and not node2:
continue
if not node1 or not node2 or node1.val != node2.val:
return False
stack.append((node1.right, node2.right))
stack.append((node1.left, node2.left))
return TrueTime & Space Complexity
- Time complexity:
- Space complexity:
3. Breadth First Search
Intuition
BFS (level-order traversal) lets us compare the two trees level by level.
We maintain two queues—one for each tree. At every step, we remove a pair of nodes
that should match:
- If both nodes are
null, they match → continue. - If only one is
null, or their values differ → trees are not the same. - If they match, we push their children into their respective queues
in the same order: left child first, then right child.
Algorithm
- Initialize two queues:
q1containing the root of the first tree.q2containing the root of the second tree.
- While both queues are non-empty:
- Pop one node from each queue:
nodeP,nodeQ. - If both are
null, continue. - If only one is
null, returnfalse. - If their values differ, return
false. - Enqueue their children:
- Left children of both trees.
- Right children of both trees.
- Pop one node from each queue:
- After BFS completes with no mismatch, return
true.
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
q1 = deque([p])
q2 = deque([q])
while q1 and q2:
for _ in range(len(q1)):
nodeP = q1.popleft()
nodeQ = q2.popleft()
if nodeP is None and nodeQ is None:
continue
if nodeP is None or nodeQ is None or nodeP.val != nodeQ.val:
return False
q1.append(nodeP.left)
q1.append(nodeP.right)
q2.append(nodeQ.left)
q2.append(nodeQ.right)
return TrueTime & Space Complexity
- Time complexity:
- Space complexity:
Common Pitfalls
Incorrect Null Check Order
A common mistake is checking node values before verifying both nodes exist. If one node is null and you access its value, you get a null pointer exception. Always check if both nodes are null first, then if exactly one is null, before comparing values.
Comparing Only Values Without Structure
Some solutions compare just the values using traversals like inorder or preorder, ignoring tree structure. Two trees can have identical traversal sequences but different structures. You must verify both the values and the structural positions match at every node.
Sign in to join the discussion