Subtree of Another Tree easy
Problem Statement
Given the roots of two binary trees root
and subRoot
, return true
if there is a subtree of root
which is equivalent to subRoot
, otherwise return false
.
A subtree of a binary tree root
is a tree that consists of a node in root
and its descendants.
Example 1
Input: root = [3,4,5,1,2], subRoot = [4,1,2] Output: true
Example 2
Input: root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2] Output: false
Steps
- Tree Traversal: We need a way to traverse both trees systematically. Depth-First Search (DFS) is a good choice.
- Subtree Check: Create a function that checks if two trees are identical. This function will compare the nodes recursively.
- Main Logic: Traverse the main tree (
root
). At each node, compare the subtree rooted at that node withsubRoot
. If a match is found, returntrue
.
Explanation
The solution uses a recursive approach. The core idea is to check if the subtree rooted at each node in the main tree matches the subRoot
tree. The isSameTree
function compares two trees for structural and value equality. The isSubtree
function performs a DFS traversal of the main tree, invoking isSameTree
at each node to check for a match.
Code
class TreeNode {
val: number;
left: TreeNode | null;
right: TreeNode | null;
constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
this.val = val === undefined ? 0 : val;
this.left = left === undefined ? null : left;
this.right = right === undefined ? null : right;
}
}
function isSameTree(p: TreeNode | null, q: TreeNode | null): boolean {
if (p === null && q === null) return true;
if (p === null || q === null) return false;
return (
p.val === q.val &&
isSameTree(p.left, q.left) &&
isSameTree(p.right, q.right)
);
}
function isSubtree(root: TreeNode | null, subRoot: TreeNode | null): boolean {
if (subRoot === null) return true; //Empty subRoot is always a subtree
if (root === null) return false;
if (isSameTree(root, subRoot)) {
return true;
}
return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot);
}
//Example Usage
const root = new TreeNode(3, new TreeNode(4, new TreeNode(1), new TreeNode(2)), new TreeNode(5));
const subRoot = new TreeNode(4, new TreeNode(1), new TreeNode(2));
console.log(isSubtree(root, subRoot)); // Output: true
const root2 = new TreeNode(3, new TreeNode(4, new TreeNode(1), new TreeNode(2)), new TreeNode(5));
const subRoot2 = new TreeNode(4, new TreeNode(1), new TreeNode(2, new TreeNode(0)));
console.log(isSubtree(root2, subRoot2)); // Output: false
Complexity
- Time Complexity: O(M * N), where N is the number of nodes in
root
and M is the number of nodes insubRoot
. In the worst case,isSameTree
might be called for every node inroot
. - Space Complexity: O(max(N, M)) in the worst case due to the recursive call stack depth. The space used is proportional to the height of the taller tree.