Open In App

Check if a binary tree is subtree of another binary tree | Set 2

Last Updated : 11 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given two binary trees, check if the first tree is a subtree of the second one. A subtree of a tree T is a tree S consisting of a node in T and all of its descendants in T. 
The subtree corresponding to the root node is the entire tree; the subtree corresponding to any other node is called a proper subtree.
For example, in the following case, Tree1 is a subtree of Tree2. 

        Tree1
x
/ \
a b
\
c
Tree2
z
/ \
x e
/ \ \
a b k
\
c

 

We have discussed an O(n2) solution for this problem. In this post, the O(n) solution is discussed. The idea is based on the fact that inorder and preorder/postorder uniquely identify a binary tree. Tree S is a subtree of T if both inorder and preorder traversals of S are substrings of inorder and preorder traversals of T respectively.
Following are detailed steps.
1) Find inorder and preorder traversals of T, and store them in two auxiliary arrays inT[] and preT[].
2) Find inorder and preorder traversals of S, and store them in two auxiliary arrays inS[] and preS[].
3) If inS[] is a subarray of inT[] and preS[] is a subarray preT[], then S is a subtree of T. Else not.
We can also use postorder traversal in place of preorder in the above algorithm.
Let us consider the above example 

Inorder and Preorder traversals of the big tree are.
inT[] = {a, c, x, b, z, e, k}
preT[] = {z, x, a, c, b, e, k}
Inorder and Preorder traversals of small tree are
inS[] = {a, c, x, b}
preS[] = {x, a, c, b}
We can easily figure out that inS[] is a subarray of
inT[] and preS[] is a subarray of preT[].

EDIT

The above algorithm doesn't work for cases where a tree is present
in another tree, but not as a subtree. Consider the following example.
Tree1
x
/ \
a b
/
c
Tree2
x
/ \
a b
/ \
c d
Inorder and Preorder traversals of the big tree or Tree2 are.
inT[] = {c, a, x, b, d}
preT[] = {x, a, c, b, d}
Inorder and Preorder traversals of small tree or Tree1 are-
inS[] = {c, a, x, b}
preS[] = {x, a, c, b}
The Tree2 is not a subtree of Tree1, but inS[] and preS[] are
subarrays of inT[] and preT[] respectively.

The above algorithm can be extended to handle such cases by adding a special character whenever we encounter NULL in inorder and preorder traversals. Thanks to Shivam Goel for suggesting this extension. 
Following is the implementation of the above algorithm.
 

C++




#include <cstring>
#include <iostream>
using namespace std;
#define MAX 100
 
// Structure of a tree node
struct Node {
    char key;
    struct Node *left, *right;
};
 
// A utility function to create a new BST node
Node* newNode(char item)
{
    Node* temp = new Node;
    temp->key = item;
    temp->left = temp->right = NULL;
    return temp;
}
 
// A utility function to store inorder traversal of tree rooted
// with root in an array arr[]. Note that i is passed as reference
void storeInorder(Node* root, char arr[], int& i)
{
    if (root == NULL) {
        arr[i++] = '$';
        return;
    }
    storeInorder(root->left, arr, i);
    arr[i++] = root->key;
    storeInorder(root->right, arr, i);
}
 
// A utility function to store preorder traversal of tree rooted
// with root in an array arr[]. Note that i is passed as reference
void storePreOrder(Node* root, char arr[], int& i)
{
    if (root == NULL) {
        arr[i++] = '$';
        return;
    }
    arr[i++] = root->key;
    storePreOrder(root->left, arr, i);
    storePreOrder(root->right, arr, i);
}
 
/* This function returns true if S is a subtree of T, otherwise false */
bool isSubtree(Node* T, Node* S)
{
    /* base cases */
    if (S == NULL)
        return true;
    if (T == NULL)
        return false;
 
    // Store Inorder traversals of T and S in inT[0..m-1]
    // and inS[0..n-1] respectively
    int m = 0, n = 0;
    char inT[MAX], inS[MAX];
    storeInorder(T, inT, m);
    storeInorder(S, inS, n);
    inT[m] = '\0', inS[n] = '\0';
 
    // If inS[] is not a substring of inT[], return false
    if (strstr(inT, inS) == NULL)
        return false;
 
    // Store Preorder traversals of T and S in preT[0..m-1]
    // and preS[0..n-1] respectively
    m = 0, n = 0;
    char preT[MAX], preS[MAX];
    storePreOrder(T, preT, m);
    storePreOrder(S, preS, n);
    preT[m] = '\0', preS[n] = '\0';
 
    // If preS[] is not a substring of preT[], return false
    // Else return true
    return (strstr(preT, preS) != NULL);
}
 
// Driver program to test above function
int main()
{
    Node* T = newNode('a');
    T->left = newNode('b');
    T->right = newNode('d');
    T->left->left = newNode('c');
    T->right->right = newNode('e');
 
    Node* S = newNode('a');
    S->left = newNode('b');
    S->left->left = newNode('c');
    S->right = newNode('d');
 
    if (isSubtree(T, S))
        cout << "Yes: S is a subtree of T";
    else
        cout << "No: S is NOT a subtree of T";
 
    return 0;
}


Java




// Java program to check if binary tree
// is subtree of another binary tree
class Node {
 
    char data;
    Node left, right;
 
    Node(char item)
    {
        data = item;
        left = right = null;
    }
}
 
class Passing {
 
    int i;
    int m = 0;
    int n = 0;
}
 
class BinaryTree {
 
    static Node root;
    Passing p = new Passing();
 
    String strstr(String haystack, String needle)
    {
        if (haystack == null || needle == null) {
            return null;
        }
        int hLength = haystack.length();
        int nLength = needle.length();
        if (hLength < nLength) {
            return null;
        }
        if (nLength == 0) {
            return haystack;
        }
        for (int i = 0; i <= hLength - nLength; i++) {
            if (haystack.charAt(i) == needle.charAt(0)) {
                int j = 0;
                for (; j < nLength; j++) {
                    if (haystack.charAt(i + j) != needle.charAt(j)) {
                        break;
                    }
                }
                if (j == nLength) {
                    return haystack.substring(i);
                }
            }
        }
        return null;
    }
 
    // A utility function to store inorder traversal of tree rooted
    // with root in an array arr[]. Note that i is passed as reference
    void storeInorder(Node node, char arr[], Passing i)
    {
        if (node == null) {
            arr[i.i++] = '$';
            return;
        }
        storeInorder(node.left, arr, i);
        arr[i.i++] = node.data;
        storeInorder(node.right, arr, i);
    }
 
    // A utility function to store preorder traversal of tree rooted
    // with root in an array arr[]. Note that i is passed as reference
    void storePreOrder(Node node, char arr[], Passing i)
    {
        if (node == null) {
            arr[i.i++] = '$';
            return;
        }
        arr[i.i++] = node.data;
        storePreOrder(node.left, arr, i);
        storePreOrder(node.right, arr, i);
    }
 
    /* This function returns true if S is a subtree of T, otherwise false */
    boolean isSubtree(Node T, Node S)
    {
        /* base cases */
        if (S == null) {
            return true;
        }
        if (T == null) {
            return false;
        }
 
        // Store Inorder traversals of T and S in inT[0..m-1]
        // and inS[0..n-1] respectively
        char inT[] = new char[100];
        String op1 = String.valueOf(inT);
        char inS[] = new char[100];
        String op2 = String.valueOf(inS);
        storeInorder(T, inT, p);
        storeInorder(S, inS, p);
        inT[p.m] = '\0';
        inS[p.m] = '\0';
 
        // If inS[] is not a substring of preS[], return false
        if (strstr(op1, op2) == null) {
            return false;
        }
 
        // Store Preorder traversals of T and S in inT[0..m-1]
        // and inS[0..n-1] respectively
        p.m = 0;
        p.n = 0;
        char preT[] = new char[100];
        char preS[] = new char[100];
        String op3 = String.valueOf(preT);
        String op4 = String.valueOf(preS);
        storePreOrder(T, preT, p);
        storePreOrder(S, preS, p);
        preT[p.m] = '\0';
        preS[p.n] = '\0';
 
        // If inS[] is not a substring of preS[], return false
        // Else return true
        return (strstr(op3, op4) != null);
    }
 
    // Driver program to test above functions
    public static void main(String args[])
    {
        BinaryTree tree = new BinaryTree();
        Node T = new Node('a');
        T.left = new Node('b');
        T.right = new Node('d');
        T.left.left = new Node('c');
        T.right.right = new Node('e');
 
        Node S = new Node('a');
        S.left = new Node('b');
        S.right = new Node('d');
        S.left.left = new Node('c');
 
        if (tree.isSubtree(T, S)) {
            System.out.println("Yes, S is a subtree of T");
        }
        else {
            System.out.println("No, S is not a subtree of T");
        }
    }
}
 
// This code is contributed by Mayank Jaiswal


Python3




MAX = 100
 
# class for a tree node
class Node:
    def __init__(self):
        self.key = ' '
        self.left = None
        self.right = None
 
# A utility function to create a new BST node
def newNode(item):
    temp = Node()
    temp.key = item
    return temp
 
# A utility function to store inorder traversal of tree rooted
# with root in an array arr[]. Note that i is passed as reference
def storeInorder(root, i):
    if (root == None):
        return '$'
    res = storeInorder(root.left, i)
    res += root.key
    res += storeInorder(root.right, i)
    return res
 
# A utility function to store preorder traversal of tree rooted
# with root in an array arr[]. Note that i is passed as reference
def storePreOrder(root, i):
    if (root == None):
        return '$'
    res = root.key
    res += storePreOrder(root.left, i)
    res += storePreOrder(root.right, i)
    return res
 
# This function returns true if S is a subtree of T, otherwise false
def isSubtree(T, S):
    # base cases
    if (S == None):
        return True
    if (T == None):
        return False
 
    # Store Inorder traversals of T and S in inT[0..m-1]
    # and inS[0..n-1] respectively
    m = 0
    n = 0
    inT = storeInorder(T, m)
    inS = storeInorder(S, n)
 
    # If inS[] is not a substring of inT[], return false
    res = True
    if inS in inT:
        res = True
    else:
        res = False
    if(res == False):
        return res
 
    # Store Preorder traversals of T and S in preT[0..m-1]
    # and preS[0..n-1] respectively
    m = 0
    n = 0
    preT = storePreOrder(T, m)
    preS = storePreOrder(S, n)
 
    # If preS[] is not a substring of preT[], return false
    # Else return true
    if preS in preT:
        return True
    else:
        return False
 
# Driver program to test above function
T = newNode('a')
T.left = newNode('b')
T.right = newNode('d')
T.left.left = newNode('c')
T.right.right = newNode('e')
 
S = newNode('a')
S.left = newNode('b')
S.left.left = newNode('c')
S.right = newNode('d')
 
if (isSubtree(T, S)):
    print("Yes: S is a subtree of T")
else:
    print("No: S is NOT a subtree of T")
 
    # This code is contributed by rj13to.


C#




// C# program to check if binary tree is
// subtree of another binary tree
using System;
 
public class Node {
 
    public char data;
    public Node left, right;
 
    public Node(char item)
    {
        data = item;
        left = right = null;
    }
}
 
public class Passing {
 
    public int i;
    public int m = 0;
    public int n = 0;
}
 
public class BinaryTree {
 
    static Node root;
    Passing p = new Passing();
 
    String strstr(String haystack, String needle)
    {
        if (haystack == null || needle == null) {
            return null;
        }
        int hLength = haystack.Length;
        int nLength = needle.Length;
        if (hLength < nLength) {
            return null;
        }
        if (nLength == 0) {
            return haystack;
        }
        for (int i = 0; i <= hLength - nLength; i++) {
            if (haystack[i] == needle[0]) {
                int j = 0;
                for (; j < nLength; j++) {
                    if (haystack[i + j] != needle[j]) {
                        break;
                    }
                }
                if (j == nLength) {
                    return haystack.Substring(i);
                }
            }
        }
        return null;
    }
 
    // A utility function to store inorder
    // traversal of tree rooted with root in
    // an array arr[]. Note that i is passed as reference
    void storeInorder(Node node, char[] arr, Passing i)
    {
        if (node == null) {
            arr[i.i++] = '$';
            return;
        }
        storeInorder(node.left, arr, i);
        arr[i.i++] = node.data;
        storeInorder(node.right, arr, i);
    }
 
    // A utility function to store preorder
    // traversal of tree rooted with root in
    // an array arr[]. Note that i is passed as reference
    void storePreOrder(Node node, char[] arr, Passing i)
    {
        if (node == null) {
            arr[i.i++] = '$';
            return;
        }
        arr[i.i++] = node.data;
        storePreOrder(node.left, arr, i);
        storePreOrder(node.right, arr, i);
    }
 
    /* This function returns true if S
    is a subtree of T, otherwise false */
    bool isSubtree(Node T, Node S)
    {
        /* base cases */
        if (S == null) {
            return true;
        }
        if (T == null) {
            return false;
        }
 
        // Store Inorder traversals of T and S in inT[0..m-1]
        // and inS[0..n-1] respectively
        char[] inT = new char[100];
        String op1 = String.Join("", inT);
        char[] inS = new char[100];
        String op2 = String.Join("", inS);
        storeInorder(T, inT, p);
        storeInorder(S, inS, p);
        inT[p.m] = '\0';
        inS[p.m] = '\0';
 
        // If inS[] is not a substring of preS[], return false
        if (strstr(op1, op2) != null) {
            return false;
        }
 
        // Store Preorder traversals of T and S in inT[0..m-1]
        // and inS[0..n-1] respectively
        p.m = 0;
        p.n = 0;
        char[] preT = new char[100];
        char[] preS = new char[100];
        String op3 = String.Join("", preT);
        String op4 = String.Join("", preS);
        storePreOrder(T, preT, p);
        storePreOrder(S, preS, p);
        preT[p.m] = '\0';
        preS[p.n] = '\0';
 
        // If inS[] is not a substring of preS[], return false
        // Else return true
        return (strstr(op3, op4) != null);
    }
 
    // Driver program to test above functions
    public static void Main(String[] args)
    {
        BinaryTree tree = new BinaryTree();
        Node T = new Node('a');
        T.left = new Node('b');
        T.right = new Node('d');
        T.left.left = new Node('c');
        T.right.right = new Node('e');
 
        Node S = new Node('a');
        S.left = new Node('b');
        S.right = new Node('d');
        S.left.left = new Node('c');
 
        if (tree.isSubtree(T, S)) {
            Console.WriteLine("Yes, S is a subtree of T");
        }
        else {
            Console.WriteLine("No, S is not a subtree of T");
        }
    }
}
 
// This code contributed by Rajput-Ji


Javascript




<script>
 
const MAX = 100
 
// class for a tree node
class Node{
    constructor(){
        this.key = ' '
        this.left = null
        this.right = null
    }
}
 
// A utility function to create a new BST node
function newNode(item){
    temp = new Node()
    temp.key = item
    return temp
}
 
// A utility function to store inorder traversal of tree rooted
// with root in an array arr[]. Note that i is passed as reference
function storeInorder(root, i){
    if (root == null)
        return '$'
    res = storeInorder(root.left, i)
    res += root.key
    res += storeInorder(root.right, i)
    return res
}
 
// A utility function to store preorder traversal of tree rooted
// with root in an array arr[]. Note that i is passed as reference
function storePreOrder(root, i){
    if (root == null)
        return '$'
    res = root.key
    res += storePreOrder(root.left, i)
    res += storePreOrder(root.right, i)
    return res
}
 
// This function returns true if S is a subtree of T, otherwise false
function isSubtree(T, S){
    // base cases
    if (S == null)
        return true
    if (T == null)
        return false
 
    // Store Inorder traversals of T and S in inT[0..m-1]
    // and inS[0..n-1] respectively
    let m = 0
    let n = 0
    let inT = storeInorder(T, m)
    let inS = storeInorder(S, n)
 
    // If inS[] is not a substring of inT[], return false
    res = true
    if(inT.indexOf(inT) !== -1)
        res = true
    else
        res = false
    if(res == false)
        return res
 
    // Store Preorder traversals of T and S in preT[0..m-1]
    // and preS[0..n-1] respectively
    m = 0
    n = 0
    let preT = storePreOrder(T, m)
    let preS = storePreOrder(S, n)
 
    // If preS[] is not a substring of preT[], return false
    // Else return true
    if(preT.indexOf(preS) !== -1)
        return true
    else
        return false
}
 
// Driver program to test above function
 
let T = new newNode('a')
T.left = new newNode('b')
T.right = new newNode('d')
T.left.left = new newNode('c')
T.right.right = new newNode('e')
 
let S = new newNode('a')
S.left = new newNode('b')
S.left.left = new newNode('c')
S.right = new newNode('d')
 
if (isSubtree(T, S))
    document.write("Yes: S is a subtree of T","</br>")
else
    document.write("No: S is NOT a subtree of T","</br>")
 
// This code is contributed by shinjanpatra
 
</script>


Output

No: S is NOT a subtree of T


Time Complexity: Inorder and Preorder traversals of Binary Tree take O(n) time. The function strstr() can also be implemented in O(n) time using the KMP string matching algorithm.
Auxiliary Space: O(n)

EASY: String Serialisation Method & using KMP algorithm:-

The method is pretty similar to the String-Matching algorithms here the approach is to store the preorder of root and sub root into two strings and then find the str_subtroot in str_root if it is present return true otherwise false.

Below I am attaching the whole program to perform the above implementation I hope it is easy to understand

Algorithm :

1. Store the inorder traversal of root in tree1

2. Similarly store the inorder traversal of subRoot in tree2

3. Search tree2 in tree1 if its present return true otherwise false

Note : You can use any other string matching algorithm such as KMP algorithm, Boyer Moore Searching, Trie | (Insert and Search)

C++




// C++ program to convert a binary tree
// to its mirror
#include <bits/stdc++.h>
using namespace std;
 
/* A binary tree node has data, pointer
to left child and a pointer to right child */
 
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
 
/* Change a tree so that the roles of the left and
    right pointers are swapped at every node.
 
So the Tree1...
      3
     / \
    4   5
   / \
  1   2
 
and our Tree2 ...
     4
    / \
   1  2
      
*/
  
 
class Solution {
public:
    bool isSubtree(TreeNode* root, TreeNode* subRoot)
    {
        string tree1, tree2;
        convertPreorder(root, tree1);
        convertPreorder(subRoot, tree2);
        // when you completed the inorder traversal
          // search trer2 in tree1
          // if it is not present reaturn false
        if (tree1.find(tree2) == string::npos)
            return false;
          // otherwise return true
        return true;
    }
    // function to store the preorder values into a string
    void convertPreorder(TreeNode* root, string& s)
    {    // if it reached null pointer
        if (root == nullptr)
            s += ",#"; //append
        else {
           // otherwise store its value separated by ','
            s += "," + to_string(root->val);
            convertPreorder(root->left, s);
            convertPreorder(root->right, s);
        }
    }
 
    /* Helper function to print
    Inorder traversal.*/
    void inOrderTraversal(TreeNode *root)
    {
        if (root == NULL)
            return;
 
        inOrderTraversal(root->left);
        cout << root->val << " ";
        inOrderTraversal(root->right);
    }
 
};
 
// Driver Code
int main()
{  
    /*Creating the root tree*/
    struct TreeNode* root = new TreeNode(3);
    root->left = new TreeNode(4);
    root->right = new TreeNode(5);
    root->left->left = new  TreeNode(1);
    root->left->right = new TreeNode(2);
 
    /*Creating the subroot tree */
    struct TreeNode *subRoot = new TreeNode(4);
    subRoot->left = new TreeNode(1);
    subRoot->right = new TreeNode(2);
 
    // creating one instance of obj
    class Solution myObj;
     
    cout << "Our Tree1 and Tree2 Looks like:\n"<<endl;
    cout<< "\nTree1: ";
    myObj.inOrderTraversal(root);
    cout<< "\nTree2: ";
    myObj.inOrderTraversal(subRoot);
    // Calling the isSubtree function
    myObj.isSubtree(root,subRoot)  ? cout<<"\nYes Tree2 is subroot of Tree1\n" : cout<<"\nNo  Tree2 is not Subtree of Tree1\n"<<endl;
    return 0;
}
 
// This code is contributed by  Pursottam Sah


Java




import java.util.*;
 
public class Solution {
    public boolean isSubtree(TreeNode root, TreeNode subRoot) {
        StringBuilder tree1 = new StringBuilder();
        StringBuilder tree2 = new StringBuilder();
        convertPreorder(root, tree1);
        convertPreorder(subRoot, tree2);
        if (tree1.indexOf(tree2.toString()) == -1)
            return false;
        return true;
    }
 
    public void convertPreorder(TreeNode root, StringBuilder s) {
        if (root == null) {
            s.append(",#");
        } else {
            s.append("," + root.val);
            convertPreorder(root.left, s);
            convertPreorder(root.right, s);
        }
    }
 
    public void inOrderTraversal(TreeNode root) {
        if (root == null)
            return;
 
        inOrderTraversal(root.left);
        System.out.print(root.val + " ");
        inOrderTraversal(root.right);
    }
 
    public static void main(String[] args) {
        /*Creating the root tree*/
        TreeNode root = new TreeNode(3);
        root.left = new TreeNode(4);
        root.right = new TreeNode(5);
        root.left.left = new TreeNode(1);
        root.left.right = new TreeNode(2);
 
        /*Creating the subroot tree */
        TreeNode subRoot = new TreeNode(4);
        subRoot.left = new TreeNode(1);
        subRoot.right = new TreeNode(2);
 
        // creating one instance of obj
        Solution myObj = new Solution();
 
        System.out.println("Our Tree1 and Tree2 Looks like:\n");
        System.out.print("\nTree1: ");
        myObj.inOrderTraversal(root);
        System.out.print("\nTree2: ");
        myObj.inOrderTraversal(subRoot);
        // Calling the isSubtree function
        if (myObj.isSubtree(root, subRoot))
            System.out.println("\nYes Tree2 is subroot of Tree1\n");
        else
            System.out.println("\nNo  Tree2 is not Subtree of Tree1\n");
    }
}
 
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
 
    TreeNode() {
        val = 0;
        left = null;
        right = null;
    }
 
    TreeNode(int x) {
        val = x;
        left = null;
        right = null;
    }
 
    TreeNode(int x, TreeNode left, TreeNode right) {
        val = x;
        this.left = left;
        this.right = right;
    }
}


Python3




    # Creating the subroot
 # Definition for a binary tree node.
class TreeNode:
     def __init__(self, val=0, left=None, right=None):
          self.val = val
          self.left = left
          self.right = right
 
class Solution:
    def isSubtree(self, root: TreeNode, subRoot: TreeNode) -> bool:
        tree1 = ''
        tree2 = ''
        self.convertPreorder(root, tree1)
        self.convertPreorder(subRoot, tree2)
        if tree2 not in tree1:
            return False
        return True
 
    def convertPreorder(self, root: TreeNode, s: str) -> None:
        if root is None:
            s += ',#'
        else:
            s += ',' + str(root.val)
            self.convertPreorder(root.left, s)
            self.convertPreorder(root.right, s)
 
    def inOrderTraversal(self, root: TreeNode) -> None:
        if root is None:
            return
 
        self.inOrderTraversal(root.left)
        print(root.val, end=" ")
        self.inOrderTraversal(root.right)
 
if __name__ == '__main__':
    # Creating the root tree
    root = TreeNode(3)
    root.left = TreeNode(4)
    root.right = TreeNode(5)
    root.left.left = TreeNode(1)
    root.left.right = TreeNode(2)


C#




using System;
 
// A binary tree node has data, pointer
// to left child and a pointer to right child
public class TreeNode
{
    public int val;
    public TreeNode left, right;
 
    public TreeNode(int val = 0, TreeNode left = null, TreeNode right = null)
    {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}
 
public class Solution
{
    public bool IsSubtree(TreeNode root, TreeNode subRoot)
    {
        string tree1 = "", tree2 = "";
        ConvertPreorder(root, ref tree1);
        ConvertPreorder(subRoot, ref tree2);
        // when you completed the inorder traversal
        // search tree2 in tree1
        // if it is not present return false
        if (!tree1.Contains(tree2))
            return false;
        // otherwise return true
        return true;
    }
 
    // function to store the preorder values into a string
    public void ConvertPreorder(TreeNode root, ref string s)
    {
        // if it reached null pointer
        if (root == null)
            s += ",#"; // append
        else
        {
            // otherwise store its value separated by ','
            s += "," + root.val;
            ConvertPreorder(root.left, ref s);
            ConvertPreorder(root.right, ref s);
        }
    }
 
    // Helper function to print Inorder traversal.
    public void InOrderTraversal(TreeNode root)
    {
        if (root == null)
            return;
 
        InOrderTraversal(root.left);
        Console.Write(root.val + " ");
        InOrderTraversal(root.right);
    }
}
 
// Driver Code
public class Program
{
    static void Main(string[] args)
    {
        /*Creating the root tree*/
        TreeNode root = new TreeNode(3)
        {
            left = new TreeNode(4),
            right = new TreeNode(5)
        };
        root.left.left = new TreeNode(1);
        root.left.right = new TreeNode(2);
 
        /*Creating the subroot tree */
        TreeNode subRoot = new TreeNode(4)
        {
            left = new TreeNode(1),
            right = new TreeNode(2)
        };
 
        // creating one instance of obj
        Solution myObj = new Solution();
 
        Console.WriteLine("Our Tree1 and Tree2 Looks like:\n");
        Console.Write("Tree1: ");
        myObj.InOrderTraversal(root);
        Console.Write("\nTree2: ");
        myObj.InOrderTraversal(subRoot);
        // Calling the IsSubtree function
        bool isSubtree = myObj.IsSubtree(root, subRoot);
        Console.WriteLine(isSubtree ? "\nYes Tree2 is subtree of Tree1" : "\nNo Tree2 is not subtree of Tree1");
    }
}


Javascript




class TreeNode {
  constructor(val) {
    this.val = val;
    this.left = null;
    this.right = null;
  }
}
 
class Solution {
  isSubtree(root, subRoot) {
    const tree1 = [];
    const tree2 = [];
    this.convertPreorder(root, tree1);
    this.convertPreorder(subRoot, tree2);
     
    const tree1String = tree1.join(",");
    const tree2String = tree2.join(",");
     
    if (tree1String.indexOf(tree2String) === -1)
      return false;
     
    return true;
  }
 
  convertPreorder(root, arr) {
    if (root === null) {
      arr.push("#");
    } else {
      arr.push(root.val);
      this.convertPreorder(root.left, arr);
      this.convertPreorder(root.right, arr);
    }
  }
 
  inOrderTraversal(root) {
    if (root === null)
      return;
 
    this.inOrderTraversal(root.left);
    console.log(root.val + " ");
    this.inOrderTraversal(root.right);
  }
}
 
/*Creating the root tree*/
const root = new TreeNode(3);
root.left = new TreeNode(4);
root.right = new TreeNode(5);
root.left.left = new TreeNode(1);
root.left.right = new TreeNode(2);
 
/*Creating the subroot tree */
const subRoot = new TreeNode(4);
subRoot.left = new TreeNode(1);
subRoot.right = new TreeNode(2);
 
// creating one instance of obj
const myObj = new Solution();
 
console.log("Our Tree1 and Tree2 Looks like:\n");
console.log("\nTree1: ");
myObj.inOrderTraversal(root);
console.log("\nTree2: ");
myObj.inOrderTraversal(subRoot);
 
// Calling the isSubtree function
if (myObj.isSubtree(root, subRoot))
  console.log("\nYes Tree2 is subroot of Tree1\n");
else
  console.log("\nNo Tree2 is not Subtree of Tree1\n");
// This Code is Contributed by Veerendra_Singh_Rajpoot


Output

Our Tree1 and Tree2 Looks like:


Tree1: 1 4 2 3 5 
Tree2: 1 4 2 
Yes Tree2 is subroot of Tree1


Traversal taking O(n) and since we are also storing into the string for checking its consuming O(n) space where n represents the no. of node values 

Time Complexity : O(n)  

Auxiliary Space: O(n) 

Interviewer: can you perform even better? 

Yes we can use the KMP algorithm for string searching 

Prerequisites : Please check the KMP algorithm first  click here

Here is the implementation code  using the KMP algorithm 

C++




// C++ program to convert a binary tree
// to its mirror
#include <iostream>
#include <string>
#include <vector>
 
using namespace std;
 
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
 
class Solution {
public:
    bool isSubtree(TreeNode* root, TreeNode* subRoot) {
        return kmp(serialize(root), serialize(subRoot));
    }
 
            /* Helper function to print
    Inorder traversal.*/
    void inOrderTraversal(TreeNode *root)
    {
        if (root == NULL)
            return;
 
        inOrderTraversal(root->left);
        cout << root->val << " ";
        inOrderTraversal(root->right);
    }
private:
    bool kmp(string s, string p) { // Check if s contains p?
        vector<int> lps = getLPS(p);
        int n = s.length(), m = p.length();
        for (int i = 0, j = 0; i < n; ++i) {
            while (s[i] != p[j] && j > 0) j = lps[j-1];
            if (s[i] == p[j]) j++;
            if (j == m) return true;
        }
        return false;
    }
 
    vector<int> getLPS(string p) {
        int m = p.length();
        vector<int> lps(m);
        for (int i = 1, j = 0; i < m; ++i) {
            while (p[i] != p[j] && j > 0) j = lps[j-1];
            if (p[i] == p[j]) lps[i] = ++j;
        }
        return lps;
    }
 
    string serialize(TreeNode* root) {
        string str;
        serializeHelper(root, str);
        return str;
    }
 
    void serializeHelper(TreeNode* root, string& str) {
        if (!root) {
            str += ",#";
        } else {
            str += "," + to_string(root->val);
            serializeHelper(root->left, str);
            serializeHelper(root->right, str);
        }
    }
   
 
};
 
 
/* Change a tree so that the roles of the left and
    right pointers are swapped at every node.
 
So the Tree1...
      3
     / \
    4   5
   / \
  1   2
 
and our Tree2 ...
     4
    / \
   1  2
      
*/
// Driver Code
int main()
{  
    /*Creating the root tree*/
    struct TreeNode* root = new TreeNode(3);
    root->left = new TreeNode(4);
    root->right = new TreeNode(5);
    root->left->left = new  TreeNode(1);
    root->left->right = new TreeNode(2);
 
    /*Creating the subroot tree */
    struct TreeNode *subRoot = new TreeNode(4);
    subRoot->left = new TreeNode(1);
    subRoot->right = new TreeNode(2);
 
    // creating one instance of obj
    class Solution myObj;
     
    cout << "Our Tree1 and Tree2 Looks like:\n"<<endl;
    cout<< "\nTree1: ";
    myObj.inOrderTraversal(root);
    cout<< "\nTree2: ";
    myObj.inOrderTraversal(subRoot);
    // Calling the isSubtree function
    myObj.isSubtree(root,subRoot)  ? cout<<"\nYes Tree2 is subroot of Tree1\n" : cout<<"\nNo  Tree2 is not Subtree of Tree1\n"<<endl;
    return 0;
}
 
// This code is contributed by  Pursottam Sah


Java




class Solution {
    public boolean isSubtree(TreeNode root, TreeNode subRoot) {
        return kmp(serialize(root), serialize(subRoot));
    }
    boolean kmp(String s, String p) { // Check if s contains p?
        int[] lps = getLPS(p);
        int n = s.length(), m = p.length();
        for (int i = 0, j = 0; i < n; ++i) {
            while (s.charAt(i) != p.charAt(j) && j > 0) j = lps[j-1];
            if (s.charAt(i) == p.charAt(j)) j++;
            if (j == m) return true;
        }
        return false;
    }
    int[] getLPS(String p) {
        int m = p.length();
        int[] lps = new int[m];
        for (int i = 1, j = 0; i < m; ++i) {
            while (p.charAt(i) != p.charAt(j) && j > 0) j = lps[j-1];
            if (p.charAt(i) == p.charAt(j)) lps[i] = ++j;
        }
        return lps;
    }
    String serialize(TreeNode root) {
        StringBuilder sb = new StringBuilder();
        serialize(root, sb);
        return sb.toString();
    }
    void serialize(TreeNode root, StringBuilder sb) {
        if (root == null) {
            sb.append(",#");
        } else {
            sb.append("," + root.val);
            serialize(root.left, sb);
            serialize(root.right, sb);
        }
    }
    
    
    
    public void inOrderTraversal(TreeNode root) {
        if (root == null)
            return;
 
        inOrderTraversal(root.left);
        System.out.print(root.val + " ");
        inOrderTraversal(root.right);
    }
 
    public static void main(String[] args) {
        /*Creating the root tree*/
        TreeNode root = new TreeNode(3);
        root.left = new TreeNode(4);
        root.right = new TreeNode(5);
        root.left.left = new TreeNode(1);
        root.left.right = new TreeNode(2);
 
        /*Creating the subroot tree */
        TreeNode subRoot = new TreeNode(4);
        subRoot.left = new TreeNode(1);
        subRoot.right = new TreeNode(2);
 
        // creating one instance of obj
        Solution myObj = new Solution();
 
        System.out.println("Our Tree1 and Tree2 Looks like:\n");
        System.out.print("\nTree1: ");
        myObj.inOrderTraversal(root);
        System.out.print("\nTree2: ");
        myObj.inOrderTraversal(subRoot);
        // Calling the isSubtree function
        if (myObj.isSubtree(root, subRoot))
            System.out.println("\nYes Tree2 is subroot of Tree1\n");
        else
            System.out.println("\nNo  Tree2 is not Subtree of Tree1\n");
    }
}
 
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
 
    TreeNode() {
        val = 0;
        left = null;
        right = null;
    }
 
    TreeNode(int x) {
        val = x;
        left = null;
        right = null;
    }
 
    TreeNode(int x, TreeNode left, TreeNode right) {
        val = x;
        this.left = left;
        this.right = right;
    }
}


Python3




    # Creating the subroot
 # Definition for a binary tree node.
 
class TreeNode:
     def __init__(self, val=0, left=None, right=None):
         self.val = val
         self.left = left
         self.right = right
 
class Solution:
    def isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool:
        def serialize(root):
            if root == None:
                return ",#"
             
            return "," + str(root.val) + serialize(root.left) + serialize(root.right)
         
        def getLPS(s):
            m, j = len(s), 0
            lps = [0] * m
            for i in range(1, m):
                while s[i] != s[j] and j > 0: j = lps[j-1]
                if s[i] == s[j]:
                    j += 1
                    lps[i] = j
            return lps
         
        def kmp(s, p):
            lps = getLPS(p)
            n, m, j = len(s), len(p), 0
            for i in range(n):
                while s[i] != p[j] and j > 0: j = lps[j-1]
                if s[i] == p[j]:
                    j += 1
                    if j == m: return True
            return False
             
        return kmp(serialize(root), serialize(subRoot))
       
 if __name__ == '__main__':
    # Creating the root tree
    root = TreeNode(3)
    root.left = TreeNode(4)
    root.right = TreeNode(5)
    root.left.left = TreeNode(1)
    root.left.right = TreeNode(2)


C#




using System;
using System.Collections.Generic;
 
public class TreeNode
{
    public int val;
    public TreeNode left;
    public TreeNode right;
    public TreeNode(int x) { val = x; }
}
 
public class Solution
{
    public bool IsSubtree(TreeNode root, TreeNode subRoot)
    {
        return Kmp(Serialize(root), Serialize(subRoot));
    }
 
    // Make the InOrderTraversal method public
    public void InOrderTraversal(TreeNode root)
    {
        if (root == null)
            return;
 
        InOrderTraversal(root.left);
        Console.Write(root.val + " ");
        InOrderTraversal(root.right);
    }
 
    private bool Kmp(string s, string p)
    {
        List<int> lps = GetLPS(p);
        int n = s.Length, m = p.Length;
        for (int i = 0, j = 0; i < n; ++i)
        {
            while (s[i] != p[j] && j > 0) j = lps[j - 1];
            if (s[i] == p[j]) j++;
            if (j == m) return true;
        }
        return false;
    }
 
    private List<int> GetLPS(string p)
    {
        int m = p.Length;
        List<int> lps = new List<int>(m);
        for (int i = 1, j = 0; i < m; ++i)
        {
            while (p[i] != p[j] && j > 0) j = lps[j - 1];
            if (p[i] == p[j]) lps.Add(++j);
            else lps.Add(0);
        }
        return lps;
    }
 
    private string Serialize(TreeNode root)
    {
        string str = "";
        SerializeHelper(root, ref str);
        return str;
    }
 
    private void SerializeHelper(TreeNode root, ref string str)
    {
        if (root == null)
        {
            str += ",#";
        }
        else
        {
            str += "," + root.val;
            SerializeHelper(root.left, ref str);
            SerializeHelper(root.right, ref str);
        }
    }
}
 
class Program
{
    static void Main()
    {
        // Creating the root tree
        TreeNode root = new TreeNode(3)
        {
            left = new TreeNode(4)
            {
                left = new TreeNode(1),
                right = new TreeNode(2)
            },
            right = new TreeNode(5)
        };
 
        // Creating the subroot tree
        TreeNode subRoot = new TreeNode(4)
        {
            left = new TreeNode(1),
            right = new TreeNode(2)
        };
 
        // Creating an instance of the Solution class
        Solution myObj = new Solution();
 
        Console.WriteLine("Our Tree1 and Tree2 Looks like:\n");
        Console.Write("\nTree1: ");
        myObj.InOrderTraversal(root);
        Console.Write("\nTree2: ");
        myObj.InOrderTraversal(subRoot);
 
        // Calling the IsSubtree function
        if (myObj.IsSubtree(root, subRoot))
        {
            Console.WriteLine("\nYes, Tree2 is a subtree of Tree1\n");
        }
        else
        {
            Console.WriteLine("\nNo, Tree2 is not a subtree of Tree1\n");
        }
    }
}
 
// This code is contributed by rambabuguphka


Javascript




class TreeNode {
  constructor(val) {
    this.val = val;
    this.left = null;
    this.right = null;
  }
}
 
class Solution {
  isSubtree(root, subRoot) {
    return this.kmp(this.serialize(root), this.serialize(subRoot));
  }
 
  inOrderTraversal(root) {
    if (!root) return;
    this.inOrderTraversal(root.left);
    console.log(root.val + " ");
    this.inOrderTraversal(root.right);
  }
 
  kmp(s, p) {
    const lps = this.getLPS(p);
    const n = s.length, m = p.length;
    for (let i = 0, j = 0; i < n; ++i) {
      while (s[i] !== p[j] && j > 0) j = lps[j-1];
      if (s[i] === p[j]) j++;
      if (j === m) return true;
    }
    return false;
  }
 
  getLPS(p) {
    const m = p.length;
    const lps = new Array(m);
    for (let i = 1, j = 0; i < m; ++i) {
      while (p[i] !== p[j] && j > 0) j = lps[j-1];
      if (p[i] === p[j]) lps[i] = ++j;
    }
    return lps;
  }
 
  serialize(root) {
    const str = [];
    this.serializeHelper(root, str);
    return str.join(",");
  }
 
  serializeHelper(root, str) {
    if (!root) {
      str.push("#");
    } else {
      str.push(root.val.toString());
      this.serializeHelper(root.left, str);
      this.serializeHelper(root.right, str);
    }
  }
}
 
const root = new TreeNode(3);
root.left = new TreeNode(4);
root.right = new TreeNode(5);
root.left.left = new TreeNode(1);
root.left.right = new TreeNode(2);
 
const subRoot = new TreeNode(4);
subRoot.left = new TreeNode(1);
subRoot.right = new TreeNode(2);
 
const myObj = new Solution();
 
console.log("Our Tree1 and Tree2 Looks like:\n");
console.log("Tree1: ");
myObj.inOrderTraversal(root);
console.log("\nTree2: ");
myObj.inOrderTraversal(subRoot);
myObj.isSubtree(root, subRoot) ? console.log("\nYes Tree2 is subroot of Tree1\n") : console.log("\nNo Tree2 is not Subtree of Tree1\n");


Output

Our Tree1 and Tree2 Looks like:


Tree1: 1 4 2 3 5 
Tree2: 1 4 2 
Yes Tree2 is subroot of Tree1


Time Complexity : O(n) 

Auxiliary Space : O(n) 


 



Previous Article
Next Article

Similar Reads

Check if a Binary tree is Subtree of another Binary tree | Set 3
Given two binary trees, check if the first tree is a subtree of the second one. A subtree of a tree T is a tree S consisting of a node in T and all of its descendants in T. The subtree corresponding to the root node is the entire tree; the subtree corresponding to any other node is called a proper subtree. Examples: Input: Tree-T Tree-S 1 3 / \ / 2
15 min read
Check if a Binary Tree is subtree of another binary tree | Set 1
Given two binary trees, check if the first tree is a subtree of the second one. A subtree of a tree T is a tree S consisting of a node in T and all of its descendants in T. The subtree corresponding to the root node is the entire tree; the subtree corresponding to any other node is called a proper subtree. Examples: Input: Tree S 10 / \ 4 6 \ 30 Tr
12 min read
Check if a binary tree is subtree of another binary tree using preorder traversal : Iterative
Given two binary trees S and T, the task is the check that if S is a subtree of the Tree T. For Example: Input: Tree T - 1 / \ 2 3 / \ / \ 4 5 6 7 Tree S - 2 / \ 4 5 Output: YES Explanation: The above tree is the subtree of the tree T, Hence the output is YES Approach: The idea is to traverse both the tree in Pre-order Traversal and check for each
11 min read
Check if the given Binary Tree have a Subtree with equal no of 1's and 0's
Given a Binary Tree having data at nodes as either 0's or 1's. The task is to find out whether there exists a subtree having an equal number of 1's and 0's. Examples: Input : Output : True There are two subtrees present in the above tree where the number of 1's is equal to the number of 0's. Input : Output : False There is no such subtree present w
10 min read
Count of nodes in given N-ary tree such that their subtree is a Binary Tree
Given an N-ary tree root, the task is to find the count of nodes such that their subtree is a binary tree. Example: Input: Tree in the image below Output: 11Explanation: The nodes such that there subtree is a binary tree are {2, 8, 10, 6, 7, 3, 1, 9, 5, 11, 12}. Input: Tree in the image below Output: 9 Approach: The given problem can be solved by u
11 min read
Find the largest BST subtree in a given Binary Tree | Set 3
Largest BST in a Binary Tree | Set 3Method 3 (Shorter, Smarter and More Efficient) In this section, a different O(n) solution is discussed. This solution is simpler than the solutions discussed in Set-1 and Set-2 and works in O(n) time. In this method, we do not need to check explicitly if the binary tree is BST. A Tree is BST if the following is t
8 min read
Duplicate subtree in Binary Tree | SET 2
Given a binary tree, the task is to check whether the binary tree contains a duplicate sub-tree of size two or more. Input: A / \ B C / \ \ D E B / \ D E Output: Yes B / \ D E is the duplicate sub-tree. Input: A / \ B C / \ D E Output: No Approach: A DFS based approach has been discussed here. A queue can be used to traverse the tree in a bfs manne
8 min read
Finding if a node X is present in subtree of another node Y or vice versa for Q queries
Given a tree with N nodes and (N-1) edges and source node is at 1st position. There are Q queries, each of the type {pos, X, Y}. Perform the following operation based on the type of the query: If pos = 0, then find if Y is present in the subtree of X.If pos = 1, then find if X is present in the subtree of Y. Examples: Input: N: = 9, edges = {{1, 2}
12 min read
Find the largest Complete Subtree in a given Binary Tree
Given a Binary Tree, the task is to find the size of largest Complete sub-tree in the given Binary Tree. Complete Binary Tree - A Binary tree is Complete Binary Tree if all levels are completely filled except possibly the last level and the last level has all keys as left as possible. Note: All Perfect Binary Trees are Complete Binary tree but reve
15+ min read
Convert a Binary Tree such that every node stores the sum of all nodes in its right subtree
Given a binary tree, change the value in each node to sum of all the values in the nodes in the right subtree including its own. Examples: Input : 1 / \ 2 3 Output : 4 / \ 2 3 Input : 1 / \ 2 3 / \ \ 4 5 6 Output : 10 / \ 7 9 / \ \ 4 5 6 Approach : The idea is to traverse the given binary tree in bottom up manner. Recursively compute the sum of nod
7 min read