DSA
Subtree of Another Tree
Binary Trees. Time O(n × m), Space O(h).
Practice here
Given the roots of two binary trees root and subRoot, return true if there is a subtree of root with the same structure and node values of subRoot and false otherwise.
A subtree of a binary tree tree is a tree that consists of a node in tree and all of this node's descendants. The tree tree could also be considered as a subtree of itself.
Approach#
- Intuition: At every node in the main tree you have a candidate root that could match subRoot. If the subtree rooted there is structurally and value-identical to subRoot, return true; otherwise recurse into both children to keep looking.
- Mechanics: A helper checkIdentical performs a simultaneous DFS on both trees, returning true only when both pointers are null together, both non-null with equal values, and their left and right subtrees also match recursively. The outer isSubtree calls this helper at each node, short-circuiting as soon as a match is found.
- Trade-off: This is the natural recursive solution — simple to reason about and correct. The worst-case O(n × m) cost occurs on degenerate trees (e.g., a linked list); for balanced trees the average cost is much lower. A serialization-based approach can reduce this to O(n + m) at the expense of extra space and edge-case handling.
cpp
/**
* 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 checkIdentical(TreeNode* root1, TreeNode* root2)
{
if(!root1 && !root2)
return true;
if(!root1 || !root2)
return false;
return root1->val == root2->val && checkIdentical(root1->left, root2->left) && checkIdentical(root1->right, root2->right);
}
bool isSubtree(TreeNode* root, TreeNode* subRoot) {
if(!root)
return false;
if(checkIdentical(root, subRoot))
return true;
return isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
}
};
Time Complexity: O(n × m),
- In the worst case, for every node in the main tree (n nodes), you may need to call checkIdentical and compare it with the subRoot (which takes up to m time).
Space Complexity: O(h)
- You are using recursive DFS in both isSubtree() and checkIdentical(), so the maximum depth of the recursion stack is the height of the tree → h.