4.8 You has both very large binary trees:tl, with millions of nodes, and T2, with hundreds of nodes. Create an algorithm to decide if T2 is a subtree of Tl. A tree T2 is a subtree of TL if there exists a node n in Tl such that the subtree of n are identical to T2. That's, if you cut off the tree at node N, the both trees would be identical.
This problem gives us two trees, T1 and T2, of which T1 have millions of nodes, T2 have hundreds of nodes, let us write algorithms to determine T2 is not T1 subtree. The first thing you can do is, we have two trees in the pre-order and the middle sequence traversal, and then the results are stored in the string, if the T2 of the pre-order and the sequence traversal of the string is the T1 of the pre-order and the string traversal of the substring, then we can determine T2 is T1 subtree, see the code as follows:
Solution One:
classSolution { Public: BOOLContaintree (TreeNode *root1, TreeNode *Root2) { stringPre1, Pre2, in1, in2; Preorder (ROOT1, pre1); Preorder (Root2, pre2); Inorder (ROOT1, in1); Inorder (Root2, in2); if(Pre1.find (pre2) = = Pre1.size ()-pre2.size () && in1.find (in2) = = In1.size ()-in2.size ())return true; Else return false; } voidPreorder (TreeNode *root,string&Res) { if(!root)return; Res.append (to_string (Root-val)); Preorder (Root-Left , RES); Preorder (Root-Right , res); } voidInorder (TreeNode *root,string&Res) { if(!root)return; Inorder (Root-Left , RES); Res.append (to_string (Root-val)); Inorder (Root-Right , res); }};
But there are exceptions to this solution that cannot be resolved correctly, such as the following two trees:
3 3
/and \
3 3
Both the middle order and the pre-order traversal are the same, so the above algorithm will return true, but we know that they are two different trees, who do not contain a subtree of who, who is not. Cracking The Coding interview 5th edition This book says on page No. 235 that we can mark an empty node, but this method is cumbersome and occupies space, so I'm not going to write it here. Here is another solution given in the book, the idea of this solution is that we first determine whether T2 is empty, NULL is the direct return to true, because the empty tree is any tree subtree, and then we see whether T1 is empty, the T1 is empty directly return false, because the empty tree can not have a nonempty tree, Then we see whether the value of the two root nodes is the same, if the same, call the Matchtree method to compare the entire T2 tree, if the exact match returns true, otherwise continue to recursively, see the code below:
Solution Two:
classSolution { Public: BOOLContaintree (TreeNode *root1, TreeNode *Root2) { if(!ROOT2)return true; if(!ROOT1)return false; if(Root1->val = = root2->val) { if(Matchtree (ROOT1, Root2))return true; } returnContaintree (Root1->left, root2) | | Containtree (root1->Right , Root2); } BOOLMatchtree (TreeNode *root1, TreeNode *Root2) { if(!root1 &&!root2)return true; if(!root1 | |!root2)return false; if(Root1->val! = root2->val)return false; Else(Matchtree (Root1->left, Root2->left) && matchtree (Root1->right, root2->Right )); }};
[Careercup] 4.8 contain tree contains trees