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 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++



filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
// 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<string> subtrees;
  
// Function that returns true if
// tree contains a duplicate subtree
// of size 2 or more
bool 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 code
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');
  
    cout << (dupSubUtil(root) ? "Yes" : "No");
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach 
import java.util.*;
class GFG
{
  
// Structure for a binary tree node
static class Node 
{
    char key;
    Node left, right;
};
  
// A utility function to create a new node
static 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 more
static 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 code
public 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;
using System.Collections.Generic;
  
class GFG
{
  
// Structure for a binary tree node
public class Node 
{
    public char key;
    public Node left, right;
};
  
// A utility function to create a new node
static 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 more
static 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 code
public 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

chevron_right


Output:

Yes


My Personal Notes arrow_drop_up

Competitive Programmer, Full Stack Developer, Technical Content Writer, Machine Learner

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : princiraj1992



Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.