Recursive DFS
Intuition
The most natural approach is to compare both trees simultaneously using recursion. At each step, we check whether the current nodes of both trees match -- both null means equal, one null means different, and different values means different. If the current nodes match, we recursively compare their left and right subtrees. Both subtrees must match for the trees to be the same. This divide-and-conquer approach elegantly mirrors the tree structure.
Algorithm
- If both p and q are null, return true (both subtrees are empty).
- If only one of p or q is null, return false (structural mismatch).
- If p.val is not equal to q.val, return false (value mismatch).
- Recursively check that the left subtrees are the same AND the right subtrees are the same.
- Return the logical AND of both recursive results.
O(n) where n is the minimum number of nodes in either treeSpaceO(h) where h is the height of the tree (O(n) in the worst case)Code (C++ · Java · Python · Go)
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if (p == nullptr && q == nullptr) return true;
if (p == nullptr || q == nullptr) return false;
if (p->val != q->val) return false;
return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
};class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) return true;
if (p == null || q == null) return false;
if (p.val != q.val) return false;
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
}def isSameTree(p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
if not p and not q:
return True
if not p or not q:
return False
if p.val != q.val:
return False
return isSameTree(p.left, q.left) and isSameTree(p.right, q.right)func isSameTree(p *TreeNode, q *TreeNode) bool {
if p == nil && q == nil {
return true
}
if p == nil || q == nil {
return false
}
if p.Val != q.Val {
return false
}
return isSameTree(p.Left, q.Left) && isSameTree(p.Right, q.Right)
}