This approach involves using a recursive function to traverse the root tree and checking for a matching subtree starting from every node. A helper function can be used to check if trees rooted at specific nodes are identical.
Time Complexity: O(N*M), where N is the number of nodes in the root tree and M is the number of nodes in subRoot tree.
Space Complexity: O(min(N, M)), depending on the tree height during recursion.
1class Solution:
2 def isSubtree(self, root, subRoot):
3 if not root:
4 return False
5 if self.isIdentical(root, subRoot):
6 return True
7 return self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot)
8
9 def isIdentical(self, s, t):
10 if not s and not t:
11 return True
12 if not s or not t:
13 return False
14 return s.val == t.val and self.isIdentical(s.left, t.left) and self.isIdentical(s.right, t.right)
The solution follows a recursive approach where isIdentical
checks whether the trees rooted at the current nodes of root
and subRoot
are the same. If a match is found, it returns true immediately; otherwise, it checks left and right subtree relations.
Another approach to solving this problem is by converting the trees into their preorder traversal strings with marker symbols for nulls, and then checking if the subRoot string is a substring of the root string.
Time Complexity: O(N + M + N*M), where N and M are the sizes of the trees.
Space Complexity: O(N + M), for the preorder traversal strings.
1#include <string>
2#include <sstream>
3
4struct TreeNode {
5 int val;
6 TreeNode *left, *right;
7};
8
9void getPreorder(TreeNode* node, std::ostringstream& out) {
10 if (node == NULL) {
11 out << "null ";
12 return;
13 }
14 out << node->val << " ";
15 getPreorder(node->left, out);
16 getPreorder(node->right, out);
17}
18
19bool isSubtree(TreeNode* root, TreeNode* subRoot) {
20 std::ostringstream rootStream, subRootStream;
21 getPreorder(root, rootStream);
22 getPreorder(subRoot, subRootStream);
23 return rootStream.str().find(subRootStream.str()) != std::string::npos;
24}
Using ostringstream
to accumulate the preorder traversal string, this method checks if serialized subRoot is a substring of the serialized root.