GFG App
Open App
Browser
Continue

# Check if a Binary Tree contains duplicate subtrees of size 2 or more

Given a Binary Tree, check whether the Binary tree contains a duplicate sub-tree of size 2 or more.
Note: Two same leaf nodes are not considered as the subtree size of a leaf node is one.

Input :  Binary Tree

A

/    \

B        C

/   \       \

D     E       B

/  \

D    E

Output : Yes

Tree with duplicate Sub-Tree [ highlight by blue color ellipse ]

[ Method 1]
A simple solution is that, we pick every node of tree and try to find is any sub-tree of given tree is present in tree which is identical with that sub-tree. Here we can use below post to find if a subtree is present anywhere else in tree.
Check if a binary tree is subtree of another binary tree

[Method 2 ]( Efficient solution )
An Efficient solution based on tree serialization and hashing. The idea is to serialize subtrees as strings and store the strings in hash table. Once we find a serialized tree (which is not a leaf) already existing in hash-table, we return true.

Below The implementation of above idea.

## C++

 `// C++ program to find if there is a duplicate ` `// sub-tree of size 2 or more. ` `#include ` `using` `namespace` `std; `   `// Separator node ` `const` `char` `MARKER = ``'\$'``; `   `// Structure for a binary tree node ` `struct` `Node ` `{ ` `    ``char` `key; ` `    ``Node *left, *right; ` `}; `   `// A utility function to create a new node ` `Node* newNode(``char` `key) ` `{ ` `    ``Node* node = ``new` `Node; ` `    ``node->key = key; ` `    ``node->left = node->right = NULL; ` `    ``return` `node; ` `} `   `unordered_set subtrees; `   `// This function returns empty string if tree ` `// contains a duplicate subtree of size 2 or more. ` `string dupSubUtil(Node *root) ` `{ ` `    ``string s = ``""``; `   `    ``// If current node is NULL, return marker ` `    ``if` `(root == NULL) ` `        ``return` `s + MARKER; `   `    ``// If left subtree has a duplicate subtree. ` `    ``string lStr = dupSubUtil(root->left); ` `    ``if` `(lStr.compare(s) == 0) ` `    ``return` `s; `   `    ``// Do same for right subtree ` `    ``string rStr = dupSubUtil(root->right); ` `    ``if` `(rStr.compare(s) == 0) ` `    ``return` `s; `   `    ``// Serialize current subtree ` `    ``s = s + root->key + lStr + rStr; `   `    ``// If current subtree already exists in hash ` `    ``// table. [Note that size of a serialized tree ` `    ``// with single node is 3 as it has two marker ` `    ``// nodes. ` `    ``if` `(s.length() > 3 && ` `        ``subtrees.find(s) != subtrees.end()) ` `    ``return` `""``; `   `    ``subtrees.insert(s); `   `    ``return` `s; ` `} `   `// Driver program to test above functions ` `int` `main() ` `{ ` `    ``Node *root = newNode(``'A'``); ` `    ``root->left = newNode(``'B'``); ` `    ``root->right = newNode(``'C'``); ` `    ``root->left->left = newNode(``'D'``); ` `    ``root->left->right = newNode(``'E'``); ` `    ``root->right->right = newNode(``'B'``); ` `    ``root->right->right->right = newNode(``'E'``); ` `    ``root->right->right->left= newNode(``'D'``); `   `    ``string str = dupSubUtil(root); `   `    ``(str.compare(``""``) == 0) ? cout << ``" Yes "``: ` `                            ``cout << ``" No "` `; ` `    ``return` `0; ` `} `

## Java

 `// Java program to find if there is a duplicate ` `// sub-tree of size 2 or more. ` `import` `java.util.HashSet; ` `public` `class` `Main { `   `    ``static` `char` `MARKER = ``'\$'``; `   `    ``// This function returns empty string if tree ` `    ``// contains a duplicate subtree of size 2 or more. ` `    ``public` `static` `String dupSubUtil(Node root, HashSet subtrees) ` `    ``{ ` `        ``String s = ``""``; ` `    `  `        ``// If current node is NULL, return marker ` `        ``if` `(root == ``null``) ` `            ``return` `s + MARKER; ` `    `  `        ``// If left subtree has a duplicate subtree. ` `        ``String lStr = dupSubUtil(root.left,subtrees); ` `        ``if` `(lStr.equals(s)) ` `            ``return` `s; ` `    `  `        ``// Do same for right subtree ` `        ``String rStr = dupSubUtil(root.right,subtrees); ` `        ``if` `(rStr.equals(s)) ` `            ``return` `s; ` `    `  `        ``// Serialize current subtree ` `          ``// Append random char in between the value to differentiate from 11,1 and 1,11` `        ``s = s + root.data + ``"%"` `+ lStr+ ``"%"` `+ rStr;` `    `  `        ``// If current subtree already exists in hash ` `        ``// table. [Note that size of a serialized tree ` `        ``// with single node is 7 (3+4 accounting for special chars appended) ` `        ``// as it has two marker ` `        ``// nodes. ` `        ``if` `(s.length() > ``7` `&& subtrees.contains(s)) ` `            ``return` `""``; ` `    `  `        ``subtrees.add(s); ` `        ``return` `s; ` `    ``} `   `    ``//Function to find if the Binary Tree contains duplicate ` `    ``//subtrees of size 2 or more ` `    ``public` `static` `String dupSub(Node root) ` `    ``{ ` `        ``HashSet subtrees=``new` `HashSet<>(); ` `        ``return` `dupSubUtil(root,subtrees); ` `    ``} `   `    ``public` `static` `void` `main(String args[]) ` `    ``{ ` `        ``Node root = ``new` `Node(``'A'``); ` `        ``root.left = ``new` `Node(``'B'``); ` `        ``root.right = ``new` `Node(``'C'``); ` `        ``root.left.left = ``new` `Node(``'D'``); ` `        ``root.left.right = ``new` `Node(``'E'``); ` `        ``root.right.right = ``new` `Node(``'B'``); ` `        ``root.right.right.right = ``new` `Node(``'E'``); ` `        ``root.right.right.left= ``new` `Node(``'D'``); ` `        ``String str = dupSub(root); ` `        ``if``(str.equals(``""``)) ` `            ``System.out.print(``" Yes "``); ` `        ``else`    `            ``System.out.print(``" No "``); ` `    ``} ` `} `   `// A binary tree Node has data, ` `// pointer to left child ` `// and a pointer to right child ` `class` `Node { ` `    ``int` `data; ` `    ``Node left,right; ` `    ``Node(``int` `data) ` `    ``{ ` `        ``this``.data=data; ` `    ``} ` `}; ` `//This code is contributed by Gaurav Tiwari `

## Python3

 `# Python3 program to find if there is` `# a duplicate sub-tree of size 2 or more`   `# Separator node` `MARKER ``=` `'\$'`   `# Structure for a binary tree node` `class` `Node:` `    `  `    ``def` `__init__(``self``, x):` `        `  `        ``self``.key ``=` `x` `        ``self``.left ``=` `None` `        ``self``.right ``=` `None`   `subtrees ``=` `{}`   `# This function returns empty if tree` `# contains a duplicate subtree of size` `# 2 or more.` `def` `dupSubUtil(root):` `    `  `    ``global` `subtrees`   `    ``s ``=` `""`   `    ``# If current node is None, return marker` `    ``if` `(root ``=``=` `None``):` `        ``return` `s ``+` `MARKER`   `    ``# If left subtree has a duplicate subtree.` `    ``lStr ``=` `dupSubUtil(root.left)` `    `  `    ``if` `(s ``in` `lStr):` `       ``return` `s`   `    ``# Do same for right subtree` `    ``rStr ``=` `dupSubUtil(root.right)` `    `  `    ``if` `(s ``in` `rStr):` `       ``return` `s`   `    ``# Serialize current subtree` `    ``s ``=` `s ``+` `root.key ``+` `lStr ``+` `rStr`   `    ``# If current subtree already exists in hash` `    ``# table. [Note that size of a serialized tree` `    ``# with single node is 3 as it has two marker` `    ``# nodes.` `    ``if` `(``len``(s) > ``3` `and` `s ``in` `subtrees):` `       ``return` `""`   `    ``subtrees[s] ``=` `1`   `    ``return` `s`   `# Driver code` `if` `__name__ ``=``=` `'__main__'``:` `    `  `    ``root ``=` `Node(``'A'``)` `    ``root.left ``=` `Node(``'B'``)` `    ``root.right ``=` `Node(``'C'``)` `    ``root.left.left ``=` `Node(``'D'``)` `    ``root.left.right ``=` `Node(``'E'``)` `    ``root.right.right ``=` `Node(``'B'``)` `    ``root.right.right.right ``=` `Node(``'E'``)` `    ``root.right.right.left``=` `Node(``'D'``)`   `    ``str` `=` `dupSubUtil(root)`   `    ``if` `"" ``in` `str``:` `        ``print``(``" Yes "``)` `    ``else``:` `        ``print``(``" No "``)`   `# This code is contributed by mohit kumar 29`

## C#

 `// C# program to find if there is a duplicate ` `// sub-tree of size 2 or more. ` `using` `System; ` `using` `System.Collections.Generic; `   `class` `GFG ` `{ `   `    ``static` `char` `MARKER = ``'\$'``; `   `    ``// This function returns empty string if tree ` `    ``// contains a duplicate subtree of size 2 or more. ` `    ``public` `static` `String dupSubUtil(Node root, ` `                    ``HashSet subtrees) ` `    ``{ ` `        ``String s = ``""``; ` `    `  `        ``// If current node is NULL, return marker ` `        ``if` `(root == ``null``) ` `            ``return` `s + MARKER; ` `    `  `        ``// If left subtree has a duplicate subtree. ` `        ``String lStr = dupSubUtil(root.left,subtrees); ` `        ``if` `(lStr.Equals(s)) ` `            ``return` `s; ` `    `  `        ``// Do same for right subtree ` `        ``String rStr = dupSubUtil(root.right,subtrees); ` `        ``if` `(rStr.Equals(s)) ` `            ``return` `s; ` `    `  `        ``// Serialize current subtree ` `        ``s = s + root.data + lStr + rStr; ` `    `  `        ``// If current subtree already exists in hash ` `        ``// table. [Note that size of a serialized tree ` `        ``// with single node is 3 as it has two marker ` `        ``// nodes. ` `        ``if` `(s.Length > 3 && subtrees.Contains(s)) ` `            ``return` `""``; ` `    `  `        ``subtrees.Add(s); ` `        ``return` `s; ` `    ``} `   `    ``// Function to find if the Binary Tree contains ` `    ``// duplicate subtrees of size 2 or more ` `    ``public` `static` `String dupSub(Node root) ` `    ``{ ` `        ``HashSet subtrees = ``new` `HashSet(); ` `        ``return` `dupSubUtil(root,subtrees); ` `    ``} `   `    ``// Driver code ` `    ``public` `static` `void` `Main(String []args) ` `    ``{ ` `        ``Node root = ``new` `Node(``'A'``); ` `        ``root.left = ``new` `Node(``'B'``); ` `        ``root.right = ``new` `Node(``'C'``); ` `        ``root.left.left = ``new` `Node(``'D'``); ` `        ``root.left.right = ``new` `Node(``'E'``); ` `        ``root.right.right = ``new` `Node(``'B'``); ` `        ``root.right.right.right = ``new` `Node(``'E'``); ` `        ``root.right.right.left= ``new` `Node(``'D'``); ` `        ``String str = dupSub(root); ` `        ``if``(str.Equals(``""``)) ` `            ``Console.Write(``" Yes "``); ` `        ``else` `            ``Console.Write(``" No "``); ` `    ``} ` `} `   `// A binary tree Node has data, ` `// pointer to left child ` `// and a pointer to right child ` `public` `class` `Node ` `{ ` `    ``public` `int` `data; ` `    ``public` `Node left,right; ` `    ``public` `Node(``int` `data) ` `    ``{ ` `        ``this``.data = data; ` `    ``} ` `}; `   `// This code is contributed by 29AjayKumar `

## Javascript

 ``

Output

` Yes `

Time Complexity: O(n)
Auxiliary Space: O(n)

The time complexity of the above program is O(n) where n is the number of nodes in the given binary tree. We are using hashing to store the subtrees which take O(n) space for all the subtrees.

This article is contributed by Nishant Singh. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.