Open In App

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

Last Updated : 03 May, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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


Asked in : Google Interview 

Tree


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 <bits/stdc++.h>
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<string> 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<String> 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<String> 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
Python
# Python program to find if there is a duplicate
# sub-tree of size 2 or more.

# A binary tree node has data,
# pointer to left child and a
# pointer to right child


class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None


def isSame(T, S):
    if T is None and S is None:
        return True
    if T is None or S is None:
        return False
    if T.data == S.data and isSame(T.left, S.left) and isSame(T.right, S.right):
        return True
    return False


def isSubtree(T, S):
    if T is None or S is None:
        return False
    if T == S:
        return False
    return isSame(T, S) or isSubtree(T.left, S) or isSubtree(T.right, S)


def findDuplicates(T, S):
    if T is None or S is None:
        return False
    if S.left is None and S.right is None:
        return False
    if T != S:
        if isSubtree(T, S):
            return True
    left = findDuplicates(T, S.left)
    if left:
        return True
    right = findDuplicates(T, S.right)
    return right


def dupSub(root):
    if root is None:
        return 0
    return 1 if findDuplicates(root, root) else 0


# Driver code
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')

if dupSub(root):
    print("Yes")
else:
    print("No")
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<String> 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<String> subtrees = new HashSet<String>();
        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
// Javascript program to find if there is a duplicate
// sub-tree of size 2 or more.
    
    let MARKER = '$';
    
    // A binary tree Node has data,
// pointer to left child
// and a pointer to right child
    class Node {
        constructor(data)
        {
            this.data=data;
        }
    }
    
    // This function returns empty string if tree
    // contains a duplicate subtree of size 2 or more.
    function dupSubUtil(root,subtrees)
    {
        let s = "";
     
        // If current node is NULL, return marker
        if (root == null)
            return s + MARKER;
     
        // If left subtree has a duplicate subtree.
        let lStr = dupSubUtil(root.left,subtrees);
        if (lStr==(s))
            return s;
     
        // Do same for right subtree
        let rStr = dupSubUtil(root.right,subtrees);
        if (rStr==(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.has(s))
            return "";
     
        subtrees.add(s);
        return s;
    }
    
    //Function to find if the Binary Tree contains duplicate
    //subtrees of size 2 or more
    function dupSub(root)
    {
            let subtrees=new Set();
            
            return dupSubUtil(root,subtrees);
    }
    
    let 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');
    let str = dupSub(root);
    if(str==(""))
        console.log(" Yes ");
     else   
        console.log(" No ");
    

// This code is contributed by unknown2108

Output
 Yes 

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



Previous Article
Next Article

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. Input: 1 N 2 3 N 4 5 6 N N N NOutput: 0Explanati
6 min read
Find All Duplicate Subtrees
Given a binary tree, 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. Examples: Input : 1 / \ 2 3 / / \ 4 2 4 / 4 Output : 2 / and 4 4 Explanation: Above Trees are two duplicate subtrees. Therefore, yo
7 min read
Count of subtrees in a Binary Tree having bitwise OR value K
Given a value K and a binary tree, the task is to find out the number of subtrees having bitwise OR of all its elements equal to K. Examples: Input: K = 5, Tree = 2 / \ 1 1 / \ \ 10 5 4 Output: 2 Explanation: Subtree 1: 5 It has only one element i.e. 5. So bitwise OR of subtree = 5 Subtree 2: 1 \ 4 it has 2 elements and bitwise OR of them is also 5
8 min read
Print updated levels of each node of a Complete Binary Tree based on difference in weights of subtrees
Given a complete binary tree with N levels numbered [0, (N - 1 )] from root to the lowest level in decreasing order and having weights numbered between [1, 2N - 1] from the root to the last leaf node in the increasing order, the task for every node is to adjust the values of the levels of all nodes present in its left and right subtree based on the
15+ min read
Remove all subtrees consisting only of even valued nodes from a Binary Tree
Given a Binary Tree, the task is to remove all the subtrees that do not contain any odd valued node. Print the Levelorder Traversal of the tree after removal of these subtrees. Note: Print NULL for removed nodes. Examples: Input: Below is the given Tree: 1 \ 2 / \ 8 5Output: 1 NULL 2 NULL 5Explanation:Tree after pruning: 1 \ 2 \ 5 Input: Below is t
8 min read
Minimize absolute difference between sum of subtrees formed after splitting Binary tree into two
Given a binary tree consisting of N nodes, the task is to split the binary tree into two subtrees by removing one edge such that the absolute difference of the sum of the subtrees is minimized. Example: Input: 1 / \ 2 3 / \ \ 4 5 8 / \ 6 7 Output: 6Explanation: Split the tree between vertex 3 and 8. Subtrees created have sums 21 and 15 Input: 1 / \
8 min read
Count of subtrees in a Binary Tree having XOR value K
Given a value K and a binary tree, the task is to find out number of subtrees having XOR of all its elements equal to K.Examples: Input K = 5, Tree = 2 / \ 1 9 / \ 10 5Output: 2Explanation:Subtree 1: 5It has only one element i.e. 5.So XOR of subtree = 5Subtree 1: 2 / \ 1 9 / \ 10 5It has elements 2, 1, 9, 10, 5.So XOR of subtree = 2 ^ 1 ^ 9 ^ 10 ^
14 min read
Check if the Binary Tree contains a balanced BST of size K
Given a Binary Tree and a positive integer K. The task is to check whether the Balanced BST of size K exists in a given Binary Tree or not. If it exists then print “Yes” else print “No”. Examples: Input: K = 4, Below is the given Tree: 15 / \ 10 26 / \ / \ 5 12 25 40 / / \ 20 35 50 \ 60 Output: Yes Explanation: Subtree of the given tree with size k
13 min read
Count of subtrees from an N-ary tree consisting of single colored nodes
Given a N-ary tree consisting of N nodes and a matrix edges[][] consisting of N - 1 edges of the form (X, Y) denoting the edge between node X and node Y and an array col[] consisting of values: 0: Uncolored node.1: Node colored red.2: Node colored blue. The task is to find the number of subtrees of the given tree which consists of only single-color
13 min read
Count of subtrees possible from an N-ary Tree
Given an N-ary tree consisting of N nodes having values 0 to (N - 1), the task is to find the total number of subtrees present in the given tree. Since the count can be very large, so print the count modulo 1000000007. Examples: Input: N = 3 0 / 1 /2Output: 7Explanation:The total number of subtrees nodes are {}, {0}, {1}, {2}, {0, 1}, {1, 2}, {0, 1
9 min read
Article Tags :
Practice Tags :