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.
1#include <stdbool.h>
2
3struct TreeNode {
4 int val;
5 struct TreeNode *left;
6 struct TreeNode *right;
7};
8
9bool isIdentical(struct TreeNode* s, struct TreeNode* t) {
10 if (!s && !t) return true;
11 if (!s || !t) return false;
12 return (s->val == t->val) && isIdentical(s->left, t->left) && isIdentical(s->right, t->right);
13}
14
15bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot) {
16 if (!root) return false;
17 if (isIdentical(root, subRoot)) return true;
18 return isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
19}
The function isIdentical
compares two trees recursively to check if they are identical. The main function isSubtree
checks the root node against the subRoot using isIdentical
and then calls itself recursively on the left and right children of the root node.
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 <stdbool.h>
2#include <string.h>
3#include <stdio.h>
4
5struct TreeNode {
6 int val;
7 struct TreeNode *left, *right;
8};
9
10void preorder(struct TreeNode* node, char *s) {
11 if (node == NULL) {
12 strcat(s, "null ");
13 return;
14 }
15 char buffer[12];
16 sprintf(buffer, "%d ", node->val);
17 strcat(s, buffer);
18 preorder(node->left, s);
19 preorder(node->right, s);
20}
21
22bool isSubstring(char* s1, char* s2) {
23 return strstr(s1, s2) != NULL;
24}
25
26bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot) {
27 char rootString[10000] = "";
28 char subRootString[10000] = "";
29 preorder(root, rootString);
30 preorder(subRoot, subRootString);
31 return isSubstring(rootString, subRootString);
32}
This approach serializes both trees using a preorder traversal which handles null
nodes explicitly. The serialized string of subRoot
is then checked as a substring within that of root
.