Check if a Binary Tree is subtree of another Binary Tree
Last Updated : 1 Aug, 2026
Given the roots of two binary trees, root1 and root2, determine whether the tree rooted at root2 is a subtree of the tree rooted at root1. Return true if there exists a node in the tree rooted at root1 such that the subtree rooted at that node is identical to the tree rooted at root2. Otherwise, return false.
Note: Two binary trees are considered identical if they have the same structure and the same node values.
Examples:
Input: root1 = [1, 2, 3, N, N, 4], root2 = [3, 4]
Output: true Explanation: In the tree rooted at root1, the subtree starting at node 3 is identical to the tree rooted at root2 (same structure and node values). Hence, root2 is a subtree of root1, so the output is true.
Input: root1 = [26, 10, N, 20, 30, 40, 60], root2 = [26, 10, N, 20, 30, 40, 60]
Output: true Explanation: Both root1 and root2 represent identical trees. So, root2 is a subtree of root1, and the output is true.
[Naive Approach] Preorder Traversal with Subtree Matching - O(n * m) Time and O(n + m) Space
The idea is to traverse the main tree (root1) in preorder. At each node, treat it as a potential root and check whether the subtree rooted at this node is identical to root2. The identical check is done by recursively comparing both trees for matching structure and node values. Return true if a match is found at any node, otherwise, continue the traversal.
Working of Approach:
Start from every node in the main tree and check whether the subtree rooted at that node is identical to root2.
The areIdentical() function recursively compares the current nodes and their left and right subtrees.
If an identical subtree is found at any node, return true immediately.
Otherwise, recursively search for the subtree in the left and right children of the current node.
If no matching subtree exists after traversing the entire tree, return false.
C++
#include<iostream>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intvalue){data=value;left=right=nullptr;}};// Check if two trees are identicalboolareIdentical(Node*root1,Node*root2){// Both nodes are null → identicalif(root1==nullptr&&root2==nullptr)returntrue;// One is null => not identicalif(root1==nullptr||root2==nullptr)returnfalse;// Check current node and recurse on childrenreturn(root1->data==root2->data&&areIdentical(root1->left,root2->left)&&areIdentical(root1->right,root2->right));}boolisSubTree(Node*root1,Node*root2){// Empty subtree => always trueif(root2==nullptr)returntrue;// Main tree empty but subtree not => falseif(root1==nullptr)returnfalse;// Match found at current nodeif(areIdentical(root1,root2))returntrue;// Otherwise, search in left and rightreturnisSubTree(root1->left,root2)||isSubTree(root1->right,root2);}intmain(){// Tree 1Node*root1=newNode(26);root1->left=newNode(10);// root1->right = nullptr (N)root1->left->left=newNode(20);root1->left->right=newNode(30);root1->left->left->left=newNode(40);root1->left->left->right=newNode(60);// Tree 2Node*root2=newNode(26);root2->left=newNode(10);// root2->right = nullptr (N)root2->left->left=newNode(20);root2->left->right=newNode(30);root2->left->left->left=newNode(40);root2->left->left->right=newNode(60);cout<<(isSubTree(root1,root2)?"true":"false");return0;}
Java
importjava.util.*;classNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intvalue){data=value;left=right=null;}}publicclassGFG{// Check if two trees are identicalpublicstaticbooleanareIdentical(Noderoot1,Noderoot2){// Both nodes are null → identicalif(root1==null&&root2==null)returntrue;// One is null => not identicalif(root1==null||root2==null)returnfalse;// Check current node and recurse on childrenreturn(root1.data==root2.data&&areIdentical(root1.left,root2.left)&&areIdentical(root1.right,root2.right));}publicstaticbooleanisSubTree(Noderoot1,Noderoot2){// Empty subtree => always trueif(root2==null)returntrue;// Main tree empty but subtree not => falseif(root1==null)returnfalse;// Match found at current nodeif(areIdentical(root1,root2))returntrue;// Otherwise, search in left and rightreturnisSubTree(root1.left,root2)||isSubTree(root1.right,root2);}publicstaticvoidmain(String[]args){// Tree 1Noderoot1=newNode(26);root1.left=newNode(10);// root1.right = null (N)root1.left.left=newNode(20);root1.left.right=newNode(30);root1.left.left.left=newNode(40);root1.left.left.right=newNode(60);// Tree 2Noderoot2=newNode(26);root2.left=newNode(10);// root2.right = null (N)root2.left.left=newNode(20);root2.left.right=newNode(30);root2.left.left.left=newNode(40);root2.left.left.right=newNode(60);System.out.println(isSubTree(root1,root2)?"true":"false");}}
Python
classNode:def__init__(self,value):self.data=valueself.left=Noneself.right=None# Check if two trees are identicaldefareIdentical(root1,root2):# Both nodes are null → identicalifroot1isNoneandroot2isNone:returnTrue# One is null => not identicalifroot1isNoneorroot2isNone:returnFalse# Check current node and recurse on childrenreturn(root1.data==root2.dataandareIdentical(root1.left,root2.left)andareIdentical(root1.right,root2.right))defisSubTree(root1,root2):# Empty subtree => always trueifroot2isNone:returnTrue# Main tree empty but subtree not => falseifroot1isNone:returnFalse# Match found at current nodeifareIdentical(root1,root2):returnTrue# Otherwise, search in left and rightreturnisSubTree(root1.left,root2)orisSubTree(root1.right,root2)if__name__=="__main__":# Tree 1root1=Node(26)root1.left=Node(10)# root1.right = None (N)root1.left.left=Node(20)root1.left.right=Node(30)root1.left.left.left=Node(40)root1.left.left.right=Node(60)# Tree 2root2=Node(26)root2.left=Node(10)# root2.right = None (N)root2.left.left=Node(20)root2.left.right=Node(30)root2.left.left.left=Node(40)root2.left.left.right=Node(60)print("true"ifisSubTree(root1,root2)else"false")
C#
usingSystem;publicclassNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intvalue){data=value;left=right=null;}}publicclassGFG{// Check if two trees are identicalpublicstaticboolAreIdentical(Noderoot1,Noderoot2){// Both nodes are null → identicalif(root1==null&&root2==null)returntrue;// One is null => not identicalif(root1==null||root2==null)returnfalse;// Check current node and recurse on childrenreturn(root1.data==root2.data&&AreIdentical(root1.left,root2.left)&&AreIdentical(root1.right,root2.right));}publicstaticboolisSubTree(Noderoot1,Noderoot2){// Empty subtree => always trueif(root2==null)returntrue;// Main tree empty but subtree not => falseif(root1==null)returnfalse;// Match found at current nodeif(AreIdentical(root1,root2))returntrue;// Otherwise, search in left and rightreturnisSubTree(root1.left,root2)||isSubTree(root1.right,root2);}publicstaticvoidMain(){// Tree 1Noderoot1=newNode(26);root1.left=newNode(10);// root1.right = null (N)root1.left.left=newNode(20);root1.left.right=newNode(30);root1.left.left.left=newNode(40);root1.left.left.right=newNode(60);// Tree 2Noderoot2=newNode(26);root2.left=newNode(10);// root2.right = null (N)root2.left.left=newNode(20);root2.left.right=newNode(30);root2.left.left.left=newNode(40);root2.left.left.right=newNode(60);Console.WriteLine(isSubTree(root1,root2)?"true":"false");}}
JavaScript
classNode{constructor(value){this.data=value;this.left=null;this.right=null;}}// Check if two trees are identicalfunctionareIdentical(root1,root2){// Both nodes are null → identicalif(root1===null&&root2===null)returntrue;// One is null => not identicalif(root1===null||root2===null)returnfalse;// Check current node and recurse on childrenreturn(root1.data===root2.data&&areIdentical(root1.left,root2.left)&&areIdentical(root1.right,root2.right));}functionisSubTree(root1,root2){// Empty subtree => always trueif(root2===null)returntrue;// Main tree empty but subtree not => falseif(root1===null)returnfalse;// Match found at current nodeif(areIdentical(root1,root2))returntrue;// Otherwise, search in left and rightreturnisSubTree(root1.left,root2)||isSubTree(root1.right,root2);}// Driver Code// Tree 1letroot1=newNode(26);root1.left=newNode(10);// root1.right = null (N)root1.left.left=newNode(20);root1.left.right=newNode(30);root1.left.left.left=newNode(40);root1.left.left.right=newNode(60);// Tree 2letroot2=newNode(26);root2.left=newNode(10);// root2.right = null (N)root2.left.left=newNode(20);root2.left.right=newNode(30);root2.left.left.left=newNode(40);root2.left.left.right=newNode(60);console.log(isSubTree(root1,root2)?"true":"false");
Output
true
[Alternate Approach] Using String Serialisation with Substring Matching - O(n * m) Time and O(n + m) Space
Convert both trees into strings using preorder traversal, and include a special marker (like #) for every null node to preserve the exact structure of the tree. This ensures that different tree structures do not produce the same serialised string. Once both trees are serialised, check if the serialised string of root2 is a substring of the serialised string of root1. If it is found, then root2 is a subtree of root1.
Why this works?
Preorder traversal visits nodes in Root -> Left -> Right order, preserving the relative order of all nodes.
A # marker is added for every NULL child so that the exact tree structure is also stored.
Separators are used between values to avoid incorrect matches (for example, 1 2 should not match 12).
Since both values and structure are preserved, every binary tree gets a unique serialized representation.
Therefore, the subtree check reduces to a simple substring search between the two serialized strings.
C++
#include<iostream>#include<string>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intvalue){data=value;left=right=nullptr;}};// Serialize tree using preorder with null markersvoidserialize(Node*root,string&s){// Null node then add markerif(root==nullptr){s+=" #";return;}// Add current nodes+=" "+to_string(root->data);// Recurse on left and rightserialize(root->left,s);serialize(root->right,s);}boolisSubTree(Node*root1,Node*root2){strings1="",s2="";// Serialize both treesserialize(root1,s1);serialize(root2,s2);// Check substringreturn(s1.find(s2)!=string::npos);}intmain(){// Tree 1Node*root1=newNode(26);root1->left=newNode(10);// root1->right = nullptr (N)root1->left->left=newNode(20);root1->left->right=newNode(30);root1->left->left->left=newNode(40);root1->left->left->right=newNode(60);// Tree 2Node*root2=newNode(26);root2->left=newNode(10);// root2->right = nullptr (N)root2->left->left=newNode(20);root2->left->right=newNode(30);root2->left->left->left=newNode(40);root2->left->left->right=newNode(60);cout<<(isSubTree(root1,root2)?"true":"false");return0;}
Java
classNode{intdata;Nodeleft,right;Node(intvalue){data=value;left=right=null;}}publicclassGFG{// Serialize tree using preorder with null markersstaticvoidserialize(Noderoot,StringBuilders){// Null node then add markerif(root==null){s.append(" #");return;}// Add current nodes.append(" ").append(root.data);// Recurse on left and rightserialize(root.left,s);serialize(root.right,s);}staticbooleanisSubTree(Noderoot1,Noderoot2){StringBuilders1=newStringBuilder();StringBuilders2=newStringBuilder();// Serialize both treesserialize(root1,s1);serialize(root2,s2);// Check substringreturns1.toString().contains(s2.toString());}publicstaticvoidmain(String[]args){// Tree 1Noderoot1=newNode(26);root1.left=newNode(10);// root1.right = null (N)root1.left.left=newNode(20);root1.left.right=newNode(30);root1.left.left.left=newNode(40);root1.left.left.right=newNode(60);// Tree 2Noderoot2=newNode(26);root2.left=newNode(10);// root2.right = null (N)root2.left.left=newNode(20);root2.left.right=newNode(30);root2.left.left.left=newNode(40);root2.left.left.right=newNode(60);System.out.println(isSubTree(root1,root2)?"true":"false");}}
Python
classNode:def__init__(self,value):self.data=valueself.left=Noneself.right=None# Serialize tree using preorder with null markersdefserialize(root):# Null node => add markerifrootisNone:return",#,"# Add current node and recurse on left and rightreturn(","+str(root.data)+","+serialize(root.left)+serialize(root.right))defisSubTree(root1,root2):# Serialize both treess1=serialize(root1)s2=serialize(root2)# Check substringreturns2ins1if__name__=="__main__":# Tree 1root1=Node(26)root1.left=Node(10)root1.left.left=Node(20)root1.left.right=Node(30)root1.left.left.left=Node(40)root1.left.left.right=Node(60)# Tree 2root2=Node(26)root2.left=Node(10)root2.left.left=Node(20)root2.left.right=Node(30)root2.left.left.left=Node(40)root2.left.left.right=Node(60)print("true"ifisSubTree(root1,root2)else"false")
C#
usingSystem;usingSystem.Text;classNode{publicintdata;publicNodeleft,right;publicNode(intvalue){data=value;left=right=null;}}classGFG{// Serialize tree using preorder with null markersstaticvoidSerialize(Noderoot,StringBuilders){// Null node then add markerif(root==null){s.Append(" #");return;}// Add current nodes.Append(" ").Append(root.data);// Recurse on left and rightSerialize(root.left,s);Serialize(root.right,s);}staticboolisSubTree(Noderoot1,Noderoot2){StringBuilders1=newStringBuilder();StringBuilders2=newStringBuilder();// Serialize both treesSerialize(root1,s1);Serialize(root2,s2);// Check substringreturns1.ToString().Contains(s2.ToString());}staticvoidMain(){// Tree 1Noderoot1=newNode(26);root1.left=newNode(10);// root1.right = null (N)root1.left.left=newNode(20);root1.left.right=newNode(30);root1.left.left.left=newNode(40);root1.left.left.right=newNode(60);// Tree 2Noderoot2=newNode(26);root2.left=newNode(10);// root2.right = null (N)root2.left.left=newNode(20);root2.left.right=newNode(30);root2.left.left.left=newNode(40);root2.left.left.right=newNode(60);Console.WriteLine(isSubTree(root1,root2)?"true":"false");}}
JavaScript
// Definition of a binary tree nodefunctionNode(value){this.data=value;this.left=null;this.right=null;}// Serialize tree using preorder with null markersfunctionserialize(root){// Null node => add markerif(root===null)return",#,";// Add current node and recurse on left and rightreturn(","+root.data+","+serialize(root.left)+serialize(root.right));}// Check if root2 is a subtree of root1functionisSubTree(root1,root2){// Serialize both treeslets1=serialize(root1);lets2=serialize(root2);// Check substringreturns1.includes(s2);}// Driver Code// Tree 1letroot1=newNode(26);root1.left=newNode(10);// root1.right = null (N)root1.left.left=newNode(20);root1.left.right=newNode(30);root1.left.left.left=newNode(40);root1.left.left.right=newNode(60);// Tree 2letroot2=newNode(26);root2.left=newNode(10);// root2.right = null (N)root2.left.left=newNode(20);root2.left.right=newNode(30);root2.left.left.left=newNode(40);root2.left.left.right=newNode(60);console.log(isSubTree(root1,root2)?"true":"false");
Output
true
[Expected Approach] Using String Serialisation with KMP algorithm - O(n + m) Time and O(n + m) Space
This is mainly an optimization over the above approach. The idea is to use KMP algorithm for substring check to ensure that we have overall linear time complexity. Similar to this approach another methods can also be used for substring matching like Boyer–Moore and Trie-based matching.
Working of Approach:
Serialize both root1 and root2 using preorder traversal, adding a special marker (#) for every NULL child to preserve the exact tree structure.
Construct the LPS (Longest Prefix Suffix) array for the serialized string of root2 to efficiently perform pattern matching.
Apply the KMP (Knuth-Morris-Pratt) algorithm to search for the serialized string of root2 within the serialized string of root1.
If the serialized string of root2 is found, return true since root2 is a subtree of root1.
Otherwise, return false after the KMP search completes without finding a match.
Let us understand with an example: nput: root1 = [26, 10, N, 20, 30, 40, 60], root2 = [26, 10, N, 20, 30, 40, 60]
Serialize both trees using preorder traversal with # for NULL nodes. Both trees produce the same string: 26 10 20 40 # # 60 # # 30 # # #
Build the LPS array for the serialized string of root2, which helps KMP skip unnecessary comparisons after a mismatch.
Start the KMP search by comparing the serialized string of root2 with that of root1 from left to right.
Since all characters match consecutively, KMP finds the complete pattern without any mismatch.
As the serialized string of root2 is found in the serialized string of root1, the function returns true.
C++
#include<iostream>#include<string>#include<vector>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intvalue){data=value;left=right=nullptr;}};// Serialize tree using preorder with null markersvoidserialize(Node*root,string&s){// Null node => add markerif(root==nullptr){s+=" #";return;}// Add current nodes+=" "+to_string(root->data);// Recurse on left and rightserialize(root->left,s);serialize(root->right,s);}// Build LPS array for KMPvector<int>buildLPS(string&pattern){intm=pattern.length();vector<int>lps(m,0);intlen=0,i=1;while(i<m){if(pattern[i]==pattern[len]){lps[i++]=++len;}else{if(len!=0)len=lps[len-1];elsei++;}}returnlps;}// KMP search: check if pattern exists in textboolkmpSearch(string&text,string&pattern){vector<int>lps=buildLPS(pattern);inti=0,j=0;while(i<text.length()){// Characters match => move bothif(text[i]==pattern[j]){i++;j++;}// Full pattern matchedif(j==pattern.length())returntrue;// Mismatch after some matcheselseif(i<text.length()&&text[i]!=pattern[j]){if(j!=0)j=lps[j-1];elsei++;}}returnfalse;}boolisSubTree(Node*root1,Node*root2){// Serialize both treesstrings1="",s2="";serialize(root1,s1);serialize(root2,s2);// Apply KMP to check substringreturnkmpSearch(s1,s2);}intmain(){// Tree 1Node*root1=newNode(26);root1->left=newNode(10);// root1->right = nullptr (N)root1->left->left=newNode(20);root1->left->right=newNode(30);root1->left->left->left=newNode(40);root1->left->left->right=newNode(60);// Tree 2Node*root2=newNode(26);root2->left=newNode(10);// root2->right = nullptr (N)root2->left->left=newNode(20);root2->left->right=newNode(30);root2->left->left->left=newNode(40);root2->left->left->right=newNode(60);cout<<(isSubTree(root1,root2)?"true":"false");return0;}
Java
importjava.util.*;classNode{intdata;Nodeleft,right;Node(intvalue){data=value;left=right=null;}}publicclassGFG{// Serialize tree using preorder with null markersstaticvoidserialize(Noderoot,StringBuilders){// Null node => add markerif(root==null){s.append(" #");return;}// Add current nodes.append(" ").append(root.data);// Recurse on left and rightserialize(root.left,s);serialize(root.right,s);}// Build LPS array for KMPstaticint[]buildLPS(Stringpattern){intm=pattern.length();int[]lps=newint[m];intlen=0,i=1;while(i<m){if(pattern.charAt(i)==pattern.charAt(len)){lps[i++]=++len;}else{if(len!=0)len=lps[len-1];elsei++;}}returnlps;}// KMP search: check if pattern exists in textstaticbooleankmpSearch(Stringtext,Stringpattern){int[]lps=buildLPS(pattern);inti=0,j=0;while(i<text.length()){// Characters match => move bothif(text.charAt(i)==pattern.charAt(j)){i++;j++;}// Full pattern matchedif(j==pattern.length())returntrue;// Mismatch after some matcheselseif(i<text.length()&&text.charAt(i)!=pattern.charAt(j)){if(j!=0)j=lps[j-1];elsei++;}}returnfalse;}staticbooleanisSubTree(Noderoot1,Noderoot2){StringBuilders1=newStringBuilder();StringBuilders2=newStringBuilder();// Serialize both treesserialize(root1,s1);serialize(root2,s2);// Apply KMP to check substringreturnkmpSearch(s1.toString(),s2.toString());}publicstaticvoidmain(String[]args){// Tree 1Noderoot1=newNode(26);root1.left=newNode(10);root1.left.left=newNode(20);root1.left.right=newNode(30);root1.left.left.left=newNode(40);root1.left.left.right=newNode(60);// Tree 2Noderoot2=newNode(26);root2.left=newNode(10);root2.left.left=newNode(20);root2.left.right=newNode(30);root2.left.left.left=newNode(40);root2.left.left.right=newNode(60);System.out.println(isSubTree(root1,root2)?"true":"false");}}
Python
classNode:def__init__(self,value):self.data=valueself.left=Noneself.right=None# Serialize tree using preorder with null markersdefserialize(root,s):# Null node => add markerifrootisNone:s.append(" #")return# Add current nodes.append(" "+str(root.data))# Recurse on left and rightserialize(root.left,s)serialize(root.right,s)# Build LPS array for KMPdefbuildLPS(pattern):lps=[0]*len(pattern)length=0i=1whilei<len(pattern):ifpattern[i]==pattern[length]:length+=1lps[i]=lengthi+=1else:iflength!=0:length=lps[length-1]else:i+=1returnlps# KMP searchdefkmpSearch(text,pattern):lps=buildLPS(pattern)i=j=0whilei<len(text):# Match => move bothiftext[i]==pattern[j]:i+=1j+=1# Full match foundifj==len(pattern):returnTrue# Mismatch after matchelifi<len(text)andtext[i]!=pattern[j]:ifj!=0:j=lps[j-1]else:i+=1returnFalsedefisSubTree(root1,root2):s1=[]s2=[]# Serialize both treesserialize(root1,s1)serialize(root2,s2)# Convert to stringstr1=" ".join(s1)str2=" ".join(s2)# Apply KMPreturnkmpSearch(str1,str2)if__name__=="__main__":# Tree 1root1=Node(26)root1.left=Node(10)root1.left.left=Node(20)root1.left.right=Node(30)root1.left.left.left=Node(40)root1.left.left.right=Node(60)# Tree 2root2=Node(26)root2.left=Node(10)root2.left.left=Node(20)root2.left.right=Node(30)root2.left.left.left=Node(40)root2.left.left.right=Node(60)print("true"ifisSubTree(root1,root2)else"false")
C#
usingSystem;usingSystem.Text;classNode{publicintdata;publicNodeleft,right;publicNode(intvalue){data=value;left=right=null;}}classGFG{// Serialize tree using preorder with null markersstaticvoidSerialize(Noderoot,StringBuilders){// Null node => add markerif(root==null){s.Append(" #");return;}// Add current nodes.Append(" ").Append(root.data);// Recurse on left and rightSerialize(root.left,s);Serialize(root.right,s);}// Build LPS array for KMPstaticint[]BuildLPS(stringpattern){intm=pattern.Length;int[]lps=newint[m];intlen=0,i=1;while(i<m){if(pattern[i]==pattern[len]){lps[i++]=++len;}else{if(len!=0)len=lps[len-1];elsei++;}}returnlps;}// KMP search: check if pattern exists in textstaticboolKMPSearch(stringtext,stringpattern){int[]lps=BuildLPS(pattern);inti=0,j=0;while(i<text.Length){// Characters match => move bothif(text[i]==pattern[j]){i++;j++;}// Full pattern matchedif(j==pattern.Length)returntrue;// Mismatch after some matcheselseif(i<text.Length&&text[i]!=pattern[j]){if(j!=0)j=lps[j-1];elsei++;}}returnfalse;}staticboolisSubTree(Noderoot1,Noderoot2){StringBuilders1=newStringBuilder();StringBuilders2=newStringBuilder();// Serialize both treesSerialize(root1,s1);Serialize(root2,s2);// Apply KMP to check substringreturnKMPSearch(s1.ToString(),s2.ToString());}staticvoidMain(){// Tree 1Noderoot1=newNode(26);root1.left=newNode(10);root1.left.left=newNode(20);root1.left.right=newNode(30);root1.left.left.left=newNode(40);root1.left.left.right=newNode(60);// Tree 2Noderoot2=newNode(26);root2.left=newNode(10);root2.left.left=newNode(20);root2.left.right=newNode(30);root2.left.left.left=newNode(40);root2.left.left.right=newNode(60);Console.WriteLine(isSubTree(root1,root2)?"true":"false");}}
JavaScript
// Definition of a binary tree nodefunctionNode(value){this.data=value;this.left=null;this.right=null;}// Serialize tree using preorder with null markersfunctionserialize(root){// Null node => add markerif(root===null)return" #";// Add current node and recurse on left and rightreturn(" "+root.data+serialize(root.left)+serialize(root.right));}// Build LPS array for KMPfunctionbuildLPS(pattern){letm=pattern.length;letlps=newArray(m).fill(0);letlen=0;leti=1;while(i<m){if(pattern[i]===pattern[len]){lps[i]=++len;i++;}else{if(len!==0)len=lps[len-1];elsei++;}}returnlps;}// KMP search: check if pattern exists in textfunctionkmpSearch(text,pattern){letlps=buildLPS(pattern);leti=0;letj=0;while(i<text.length){if(text[i]===pattern[j]){i++;j++;}// Full pattern matchedif(j===pattern.length)returntrue;// Mismatch after some matcheselseif(i<text.length&&text[i]!==pattern[j]){if(j!==0)j=lps[j-1];elsei++;}}returnfalse;}// Check if root2 is a subtree of root1functionisSubTree(root1,root2){// Serialize both treeslets1=serialize(root1);lets2=serialize(root2);// Apply KMP to check substringreturnkmpSearch(s1,s2);}// Driver Code// Tree 1letroot1=newNode(26);root1.left=newNode(10);root1.left.left=newNode(20);root1.left.right=newNode(30);root1.left.left.left=newNode(40);root1.left.left.right=newNode(60);// Tree 2letroot2=newNode(26);root2.left=newNode(10);root2.left.left=newNode(20);root2.left.right=newNode(30);root2.left.left.left=newNode(40);root2.left.left.right=newNode(60);console.log(isSubTree(root1,root2)?"true":"false");