Duplicate subtree in Binary Tree | SET 2 - GeeksforGeeks

23 Jun, 2021
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 manner. While traversing the nodes, push the node along with its left and right children in a map and if any point the map contains duplicates then the tree contains duplicate sub-trees. For example, if the node is A and its children are B and C then ABC will be pushed to the map. If at any point, ABC has to be pushed again then the tree contains duplicate sub-trees.Below is the implementation of the above approach: 
C++
Java
Python3
C#
Javascript
// C++ implementation of the approach#include <bits/stdc++.h>using namespace std; // Structure for a binary tree nodestruct Node {    char key;    Node *left, *right;}; // A utility function to create a new nodeNode* newNode(char key){    Node* node = new Node;    node->key = key;    node->left = node->right = NULL;    return node;} unordered_set<string> subtrees; // Function that returns true if// tree contains a duplicate subtree// of size 2 or morebool dupSubUtil(Node* root){     // To store subtrees    set<string> subtrees;     // Used to traverse tree    queue<Node*> bfs;    bfs.push(root);     while (!bfs.empty()) {        Node* n = bfs.front();        bfs.pop();         // To store the left and the right        // children of the current node        char l = ' ', r = ' ';         // If the node has a left child        if (n->left != NULL) {            l = n->left->key;             // Push left node's data            bfs.push(n->left);        }         // If the node has a right child        if (n->right != NULL) {            r = n->right->key;             // Push right node's data            bfs.push(n->right);        }         string subt;        subt += n->key;        subt += l;        subt += r;         if (l != ' ' || r != ' ') {             // If this subtree count is greater than 0            // that means duplicate exists            if (!subtrees.insert(subt).second) {                return true;            }        }    }    return false;} // Driver codeint 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');     cout << (dupSubUtil(root) ? "Yes" : "No");     return 0;}
// Java implementation of the approachimport java.util.*;class GFG{ // Structure for a binary tree nodestatic class Node{    char key;    Node left, right;}; // A utility function to create a new nodestatic Node newNode(char key){    Node node = new Node();    node.key = key;    node.left = node.right = null;    return node;} static HashSet<String> subtrees = new HashSet<String>(); // Function that returns true if// tree contains a duplicate subtree// of size 2 or morestatic boolean dupSubUtil(Node root){     // To store subtrees    // HashSet<String> subtrees;     // Used to traverse tree    Queue<Node> bfs = new LinkedList<>();    bfs.add(root);     while (!bfs.isEmpty())    {        Node n = bfs.peek();        bfs.remove();         // To store the left and the right        // children of the current node        char l = ' ', r = ' ';         // If the node has a left child        if (n.left != null)        {            l = n.left.key;             // Push left node's data            bfs.add(n.left);        }         // If the node has a right child        if (n.right != null)        {            r = n.right.key;             // Push right node's data            bfs.add(n.right);        }         String subt = "";        subt += n.key;        subt += l;        subt += r;         if (l != ' ' || r != ' ')        {             // If this subtree count is greater than 0            // that means duplicate exists            if (!subtrees.contains(subt))            {                return true;            }        }    }    return false;} // Driver codepublic static void main(String[] args){    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');    if (dupSubUtil(root))        System.out.println("Yes");    else        System.out.println("No");}} // This code is contributed by Princi Singh
# Python3 implementation of the approach # Structure for a binary tree nodeclass newNode:     # Constructor to create a new node    def __init__(self, data):        self.key = data        self.left = None        self.right = None subtrees = set() # Function that returns true if# tree contains a duplicate subtree# of size 2 or moredef dupSubUtil(root):         # To store subtrees    subtrees= set()         # Used to traverse tree    bfs = []    bfs.append(root)    while (len(bfs)):        n = bfs[0]        bfs.pop(0)                 # To store the left and the right        # children of the current node        l = ' '        r = ' '                 # If the node has a left child        if (n.left != None):            x = n.left            l = x.key                         # append left node's data            bfs.append(n.left)                     # If the node has a right child        if (n.right != None):            x = n.right            r = x.key                         # append right node's data            bfs.append(n.right)                     subt=""        subt += n.key        subt += l        subt += r                 if (l != ' ' or r != ' '):                     # If this subtree count is greater than 0            # that means duplicate exists            subtrees.add(subt)            if (len(subtrees) > 1):                return True                     return False # Driver code 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') if dupSubUtil(root):    print("Yes")else:    print("No") # This code is contributed by SHUBHAMSINGH10
// C# implementation of the approachusing System;using System.Collections.Generic; class GFG{ // Structure for a binary tree nodepublic class Node{    public char key;    public Node left, right;}; // A utility function to create a new nodestatic Node newNode(char key){    Node node = new Node();    node.key = key;    node.left = node.right = null;    return node;} static HashSet<String> subtrees = new HashSet<String>(); // Function that returns true if// tree contains a duplicate subtree// of size 2 or morestatic bool dupSubUtil(Node root){     // To store subtrees    // HashSet<String> subtrees;     // Used to traverse tree    Queue<Node> bfs = new Queue<Node>();    bfs.Enqueue(root);     while (bfs.Count != 0)    {        Node n = bfs.Peek();        bfs.Dequeue();         // To store the left and the right        // children of the current node        char l = ' ', r = ' ';         // If the node has a left child        if (n.left != null)        {            l = n.left.key;             // Push left node's data            bfs.Enqueue(n.left);        }         // If the node has a right child        if (n.right != null)        {            r = n.right.key;             // Push right node's data            bfs.Enqueue(n.right);        }         String subt = "";        subt += n.key;        subt += l;        subt += r;         if (l != ' ' || r != ' ')        {             // If this subtree count is greater than 0            // that means duplicate exists            if (!subtrees.Contains(subt))            {                return true;            }        }    }    return false;} // Driver codepublic static void Main(String[] args){    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');    if (dupSubUtil(root))        Console.WriteLine("Yes");    else        Console.WriteLine("No");}} // This code is contributed by PrinciRaj1992
<script> // Javascript implementation of the approach // Structure for a binary tree nodeclass Node{    constructor()    {        this.key = '';        this.left = null;        this.right = null;    }}; // A utility function to create a new nodefunction newNode(key){    var node = new Node();    node.key = key;    node.left = node.right = null;    return node;} var subtrees = new Set(); // Function that returns true if// tree contains a duplicate subtree// of size 2 or morefunction dupSubUtil(root){     // To store subtrees    // HashSet<String> subtrees;     // Used to traverse tree    var bfs = [];    bfs.push(root);     while (bfs.length != 0)    {        var n = bfs[0];        bfs.pop();         // To store the left and the right        // children of the current node        var l = ' ', r = ' ';         // If the node has a left child        if (n.left != null)        {            l = n.left.key;             // Push left node's data            bfs.push(n.left);        }         // If the node has a right child        if (n.right != null)        {            r = n.right.key;             // Push right node's data            bfs.push(n.right);        }         var subt = "";        subt += n.key;        subt += l;        subt += r;         if (l != ' ' || r != ' ')        {             // If this subtree count is greater than 0            // that means duplicate exists            if (!subtrees.has(subt))            {                return true;            }        }    }    return false;} // Driver codevar 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');if (dupSubUtil(root))    document.write("Yes");else    document.write("No"); // This code is contributed by rrrtnx.</script>
Yes
 
princiraj1992
SHUBHAMSINGH10
rrrtnx
BFS
Binary Tree
Queue
Tree
Queue
Tree
BFS
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Construct Complete Binary Tree from its Linked List Representation
Reversing a Queue
FIFO (First-In-First-Out) approach in Programming
Applications of Priority Queue
Iterative Method to find Height of Binary Tree
Tree Traversals (Inorder, Preorder and Postorder)
Binary Tree | Set 1 (Introduction)
AVL Tree | Set 1 (Insertion)
Inorder Tree Traversal without Recursion
Binary Tree | Set 3 (Types of Binary Tree)