Skip to content
geeksforgeeks
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • Tutorials
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
  • Practice
    • Build your AI Agent
    • GfG 160
    • Problem of the Day
    • Practice Coding Problems
    • GfG SDE Sheet
  • Contests
    • Accenture Hackathon (Ending Soon!)
    • GfG Weekly [Rated Contest]
    • Job-A-Thon Hiring Challenge
    • All Contests and Events
  • DSA
  • Interview Problems on Tree
  • Practice Tree
  • MCQs on Tree
  • Tutorial on Tree
  • Types of Trees
  • Basic operations
  • Tree Traversal
  • Binary Tree
  • Complete Binary Tree
  • Ternary Tree
  • Binary Search Tree
  • Red-Black Tree
  • AVL Tree
  • Full Binary Tree
  • B-Tree
  • Advantages & Disadvantages
Open In App
Next Article:
Find all duplicate levels of given Binary Tree
Next article icon

Duplicate subtree in Binary Tree | SET 2

Last Updated : 19 Apr, 2023
Comments
Improve
Suggest changes
Like Article
Like
Report

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




// 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;
}
 
 

Java




import java.util.*;
 
// Structure for a binary tree node
class Node {
    char key;
    Node left, right;
  
    Node(char item) {
        key = item;
        left = right = null;
    }
}
  
class Main {
    static Set<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
        Set<String> subtrees = new HashSet<String>();
  
        // Used to traverse tree
        Queue<Node> bfs = new LinkedList<Node>();
        bfs.add(root);
  
        while (!bfs.isEmpty()) {
            Node n = bfs.poll();
  
            // 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.add(subt)) {
                    return true;
                }
            }
        }
        return false;
    }
  
    // 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');
  
        System.out.println((dupSubUtil(root) ? "Yes" : "No"));
    }
}
 
 

Python3




# Python3 implementation of the approach
 
# Structure for a binary tree node
class 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 more
def 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#




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

Javascript




<script>
 
// Javascript implementation of the approach
 
// Structure for a binary tree node
class Node
{
    constructor()
    {
        this.key = '';
        this.left = null;
        this.right = null;
    }
};
 
// A utility function to create a new node
function 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 more
function 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 code
var 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>
 
 
Output: 
Yes

 

Time complexity: O(n) where N is no of nodes in a binary tree

Auxiliary Space: O(n)



Next Article
Find all duplicate levels of given Binary Tree
author
md1844
Improve
Article Tags :
  • DSA
  • Queue
  • Tree
  • BFS
  • Binary Tree
Practice Tags :
  • BFS
  • Queue
  • Tree

Similar Reads

  • Count of duplicate Subtrees in an N-ary Tree
    Given the root of an n-ary tree, the task is to find the number of subtrees that have duplicates in the n-ary tree. Two trees are duplicates if they have the same structure with the same node values. Examples: Input: 1 N 2 2 3 N 4 N 4 4 3 N N N N NOutput: 2Explanation: [4], [3] are duplicate subtree
    6 min read
  • Find all duplicate levels of given Binary Tree
    A binary tree is a tree data structure in which each node has at most two child nodes, referred to as the left and right children. In this question, the task is to find all the duplicate levels of a given binary tree. This problem can be used to identify and resolve any duplicate nodes or values in
    13 min read
  • How to handle duplicates in Binary Search Tree?
    In a Binary Search Tree (BST), all keys in the left subtree of a key must be smaller and all keys in the right subtree must be greater. So a Binary Search Tree by definition has distinct keys. How can duplicates be allowed where every insertion inserts one more key with a value and every deletion de
    15+ min read
  • Binary Tree Data Structure
    A Binary Tree Data Structure is a hierarchical data structure in which each node has at most two children, referred to as the left child and the right child. It is commonly used in computer science for efficient storage and retrieval of data, with various operations such as insertion, deletion, and
    3 min read
  • Check if a Binary Tree contains duplicate subtrees of size 2 or more
    Given a Binary Tree, the task is to 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 as the size of a leaf node is one. Example: Input: Output: TrueExplanation: Table of Content [Naive Approach] Generating All
    15 min read
  • Find All Duplicate Subtrees
    Given a binary tree, the task is to find all duplicate subtrees. For each duplicate subtree, we only need to return the root node of any one of them. Two trees are duplicates if they have the same structure with the same node values. Example: Input : Binary tree 1 / \ 2 3 / / \ 4 2 4 / 4Output : 2 /
    15+ min read
  • Double Threaded Binary Search Tree
    Double Threaded Binary Search Tree: is a binary search tree in which the nodes are not every left NULL pointer points to its inorder predecessor and the right NULL pointer points to the inorder successor.The threads are also useful for fast accessing the ancestors of a node.  Double Threaded Binary
    15+ min read
  • Find the largest Perfect Subtree in a given Binary Tree
    Given a Binary Tree, the task is to find the size of largest Perfect sub-tree in the given Binary Tree. Perfect Binary Tree - A Binary tree is Perfect Binary Tree in which all internal nodes have two children and all leaves are at the same level. Examples: Input: 1 / \ 2 3 / \ / 4 5 6 Output: Size :
    12 min read
  • Nodes at Kth level without duplicates in a Binary Tree
    Given a binary tree with N nodes and an integer K, the task is to print nodes of the Kth level of a binary tree without duplicates. Examples: Input: 60 --- Level 0 / \ 50 30 --- Level 1 / \ / 80 10 40 --- Level 2 K = 1 Output: 30 50 Input: 50 --- Level 0 / \ 60 70 --- Level 1 / \ / \ 90 40 40 20 ---
    11 min read
  • Convert given binary tree to a XOR tree
    Given a Binary Tree where each node has a value of either 0 or 1, the task is to convert the given Binary tree to an XOR tree i.e a tree such that each node value is the logical XOR between its children. Note: Leaf nodes and nodes with one child are not considered as they don't have both children. E
    8 min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences