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
Asked in : Google InterviewÂ
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++
#include<bits/stdc++.h>
using namespace std;
const char MARKER = '$' ;
struct Node
{
char key;
Node *left, *right;
};
Node* newNode( char key)
{
Node* node = new Node;
node->key = key;
node->left = node->right = NULL;
return node;
}
unordered_set<string> subtrees;
string dupSubUtil(Node *root)
{
string s = "" ;
if (root == NULL)
return s + MARKER;
string lStr = dupSubUtil(root->left);
if (lStr.compare(s) == 0)
return s;
string rStr = dupSubUtil(root->right);
if (rStr.compare(s) == 0)
return s;
s = s + root->key + lStr + rStr;
if (s.length() > 3 &&
subtrees.find(s) != subtrees.end())
return "" ;
subtrees.insert(s);
return s;
}
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
import java.util.HashSet;
public class Main {
static char MARKER = '$' ;
public static String dupSubUtil(Node root, HashSet<String> subtrees)
{
String s = "" ;
if (root == null )
return s + MARKER;
String lStr = dupSubUtil(root.left,subtrees);
if (lStr.equals(s))
return s;
String rStr = dupSubUtil(root.right,subtrees);
if (rStr.equals(s))
return s;
s = s + root.data + "%" + lStr+ "%" + rStr;
if (s.length() > 7 && subtrees.contains(s))
return "" ;
subtrees.add(s);
return s;
}
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 " );
}
}
class Node {
int data;
Node left,right;
Node( int data)
{
this .data=data;
}
};
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static char MARKER = '$' ;
public static String dupSubUtil(Node root,
HashSet<String> subtrees)
{
String s = "" ;
if (root == null )
return s + MARKER;
String lStr = dupSubUtil(root.left,subtrees);
if (lStr.Equals(s))
return s;
String rStr = dupSubUtil(root.right,subtrees);
if (rStr.Equals(s))
return s;
s = s + root.data + lStr + rStr;
if (s.Length > 3 && subtrees.Contains(s))
return "" ;
subtrees.Add(s);
return s;
}
public static String dupSub(Node root)
{
HashSet<String> subtrees = new HashSet<String>();
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( "" ))
Console.Write( " Yes " );
else
Console.Write( " No " );
}
}
public class Node
{
public int data;
public Node left,right;
public Node( int data)
{
this .data = data;
}
};
|
Javascript
let MARKER = '$' ;
class Node {
constructor(data)
{
this .data=data;
}
}
function dupSubUtil(root,subtrees)
{
let s = "" ;
if (root == null )
return s + MARKER;
let lStr = dupSubUtil(root.left,subtrees);
if (lStr==(s))
return s;
let rStr = dupSubUtil(root.right,subtrees);
if (rStr==(s))
return s;
s = s + root.data + lStr + rStr;
if (s.length > 3 && subtrees.has(s))
return "" ;
subtrees.add(s);
return s;
}
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 " );
|
Python3
class Node:
def __init__( self , key):
self .key = key
self .left = None
self .right = None
def dupSubUtil(root, subtrees):
MARKER = '$'
s = ""
if root is None :
return s + MARKER
l_str = dupSubUtil(root.left, subtrees)
if l_str = = s:
return s
r_str = dupSubUtil(root.right, subtrees)
if r_str = = s:
return s
s = s + root.key + l_str + r_str
if len (s) > 3 and s in subtrees:
return ""
subtrees.add(s)
return s
def dupSub(root):
subtrees = set ()
result = dupSubUtil(root, subtrees)
return "Yes" if result = = " " else " No"
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' )
print (dupSub(root))
|
Time Complexity: O(n)
Auxiliary Space: O(n)
Â
Last Updated :
11 Mar, 2024
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...