Question
You have two very large binary trees: T1, with millions of nodes, and T2, with hundreds of nodes. Create an algorithm to decide if T2 is a subtree of T1.
Solution 1
The best solution is to print inorder and preorder traversal of both trees. Find whether the 2 traversal string of T2 is substring of the traversal of T1. This is a very good idea of checking subtree of a Binary Tree.
Updated on Jan 26th, 2015: do we have to use sentinals for this purpose? Well, the answer is NO, cuz a preorder and a inorder can uniquely define a binary tree.
However, this solution is very memory intensive.
Solution 2
The alternative solution simply checks the tree similarity for each and every node.
Time complexity:
If k is the number of occurrences of T2’s root in T1, the worst case runtime can be characterized as O(n + k * m).
However, there can be a lot of pruning for this solution, so it’s NOT necessarily slower than Solution 1. There can be a lot of discussions on this (refer to CC150v5 Q4.8 for more).
Code
written by me
public static boolean containsTree(TreeNode t1, TreeNode t2) {
if (t1 == null) {
return false;
} else if (matchTree(t1, t2)) {
return true;
} else {
return containsTree(t1.left, t2) || containsTree(t1.right, t2);
}
}
private static boolean matchTree(TreeNode t1, TreeNode t2) {
if (t2 == null) {
return true;
} else if (t1 == null) {
return false;
} else if (t1.data != t2.data) {
return false;
} else {
return matchTree(t1.left, t2.left) && matchTree(t1.right, t2.right);
}
}