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
You should aim for a solution with O(n) time and O(n) space, where n is the number of nodes in the tree.
Can you think of an algorithm that is used to traverse the tree? Maybe in terms of recursion.
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?
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.
Before attempting this problem, you should be comfortable with:
Two binary trees are the same if:
So at every position:
null → they match.null but the other isn't → mismatch.This is a direct structural + value-based DFS comparison.
p and q are null, return true.null, return false.false.p.left with q.leftp.right with q.righttrue only if both subtree comparisons are 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:
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 FalseWhere is the number of nodes in the tree and is the height of the tree.
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:
null, they match → continue.null, or their values differ → trees are not the same.If we finish processing all pairs with no mismatch, the trees are identical.
(p, q).(node1, node2).null, continue.null, return false.node1.val != node2.val, return false.(node1.left, node2.left)(node1.right, node2.right)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 TrueBFS (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:
null, they match → continue.null, or their values differ → trees are not the same.q1 containing the root of the first tree.q2 containing the root of the second tree.nodeP, nodeQ.null, continue.null, return false.false.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 TrueA 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.
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.