Approach 1: Simple Recursive DFS Comparison (Clean & Optimal)
| LeetCode #100 | Difficulty: Easy |
Intuition
To determine if two binary trees are the same, we must verify:
- Both trees have identical structure.
- Corresponding nodes have equal values.
Since a tree is naturally defined recursively (each node has left and right subtrees), the most intuitive solution is to compare both trees recursively:
- If both nodes are null → they are equal.
- If one is null and the other is not → not equal.
- If values differ → not equal.
- Otherwise → recursively check left and right subtrees.
This directly mirrors the definition of identical trees.
Approach
We perform a Depth-First Search (DFS) on both trees simultaneously.
For each pair of nodes (p, q):
- If both are null → return true.
- If only one is null → return false.
- If values differ → return false.
- Recursively check:
- Left subtree:
isSameTree(p->left, q->left) - Right subtree:
isSameTree(p->right, q->right)
- Left subtree:
If both left and right subtree comparisons return true, the current subtree is identical.
This ensures:
- Structure equality
- Value equality
- Complete traversal of both trees
Complexity
-
Time complexity: O(n)
We visit each node exactly once. Here, n is the number of nodes in the trees.
-
Space complexity: O(h)
Due to recursion stack. In worst case (skewed tree), h = n. In balanced tree, h = log(n).
Code
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if(!p && !q) return true;
if(!p || !q) return false;
if(p->val != q->val) return false;
return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
};
Approach 2: Iterative BFS Comparison Using Queue (Level-by-Level Check)
Intuition
Two binary trees are considered the same if:
- Their structures are identical.
- Corresponding nodes have equal values.
So instead of comparing the entire trees at once, we can compare them node by node.
If at any point:
- One node exists and the other does not → trees differ.
- Node values differ → trees differ.
Otherwise, if we traverse both trees simultaneously and never find a mismatch, the trees are identical.
Approach
Instead of using recursion, we perform an iterative Breadth-First Search (BFS).
- Handle base cases:
- If one root is null and the other is not → return false.
- If both are null → return true.
- Use a queue of pairs:
- Each element stores corresponding nodes from both trees.
- Push the root pair into the queue.
- While the queue is not empty:
- Pop a pair (node1, node2).
- If values differ → return false.
- Check left children:
- If one exists and the other does not → return false.
- If both exist → push the pair into queue.
- Check right children similarly.
- If traversal completes without mismatch → return true.
This ensures both structure and values are verified simultaneously.
Complexity
-
Time complexity: O(n)
Each node is visited exactly once.
-
Space complexity: O(n)
In the worst case (complete binary tree), the queue may hold up to O(n) nodes.
Code
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if((!p && q) || (p && !q)) return false;
if(!p && !q) return true;
queue<pair<TreeNode*, TreeNode*>> nodeQ;
nodeQ.push({p, q});
while(!nodeQ.empty()) {
TreeNode* node1 = nodeQ.front().first;
TreeNode* node2 = nodeQ.front().second;
nodeQ.pop();
if(node1->val != node2->val) return false;
if((!node1->left && node2->left) || (node1->left && !node2->left))
return false;
if(node1->left && node2->left)
nodeQ.push({node1->left, node2->left});
if((!node1->right && node2->right) || (node1->right && !node2->right))
return false;
if(node1->right && node2->right)
nodeQ.push({node1->right, node2->right});
}
return true;
}
};