Open In App

Find All Duplicate Subtrees

Last Updated : 15 Jul, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

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, you need to return above trees root in the 
form of a list.
Recommended Practice

The idea is to use hashing. We store inorder traversals of subtrees in a hash. Since simple inorder traversal cannot uniquely identify a tree, we use symbols like ‘(‘ and ‘)’ to represent NULL nodes. 

We pass an Unordered Map in C++ as an argument to the helper function which recursively calculates inorder string and increases its count in map. If any string gets repeated, then it will imply duplication of the subtree rooted at that node so push that node in the Final result and return the vector of these nodes.  

Implementation:

C++




// C++ program to find averages of all levels
// in a binary tree.
#include <bits/stdc++.h>
using namespace std;
 
/* A binary tree node has data, pointer to
left child and a pointer to right child */
struct Node {
    int data;
    struct Node* left, *right;
};
 
string inorder(Node* node, unordered_map<string, int>& m)
{
    if (!node)
        return "";
 
    string str = "(";
    str += inorder(node->left, m);
    str += to_string(node->data);
    str += inorder(node->right, m);
    str += ")";
 
    // Subtree already present (Note that we use
    // unordered_map instead of unordered_set
    // because we want to print multiple duplicates
    // only once, consider example of 4 in above
    // subtree, it should be printed only once.
    if (m[str] == 1)
        cout << node->data << " ";
 
    m[str]++;
 
    return str;
}
 
// Wrapper over inorder()
void printAllDups(Node* root)
{
    unordered_map<string, int> m;
    inorder(root, m);
}
 
/* Helper function that allocates a
new node with the given data and
NULL left and right pointers. */
Node* newNode(int data)
{
    Node* temp = new Node;
    temp->data = data;
    temp->left = temp->right = NULL;
    return temp;
}
 
// Driver code
int main()
{
    Node* root = NULL;
    root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(3);
    root->left->left = newNode(4);
    root->right->left = newNode(2);
    root->right->left->left = newNode(4);
    root->right->right = newNode(4);
    printAllDups(root);
    return 0;
}


Java




// A java program to find all duplicate subtrees
// in a binary tree.
import java.util.HashMap;
public class Duplicate_subtress {
 
    /* A binary tree node has data, pointer to
    left child and a pointer to right child */
    static HashMap<String, Integer> m;
    static class Node {
        int data;
        Node left;
        Node right;
        Node(int data){
            this.data = data;
            left = null;
            right = null;
        }
    }
    static String inorder(Node node)
    {
        if (node == null)
            return "";
      
        String str = "(";
        str += inorder(node.left);
        str += Integer.toString(node.data);
        str += inorder(node.right);
        str += ")";
      
        // Subtree already present (Note that we use
        // HashMap instead of HashSet
        // because we want to print multiple duplicates
        // only once, consider example of 4 in above
        // subtree, it should be printed only once.      
        if (m.get(str) != null && m.get(str)==1 )
            System.out.print( node.data + " ");
      
        if (m.containsKey(str))
            m.put(str, m.get(str) + 1);
        else
            m.put(str, 1);
         
        
        return str;
    }
      
    // Wrapper over inorder()
    static void printAllDups(Node root)
    {
        m = new HashMap<>();
        inorder(root);
    }
    // Driver code
    public static void main(String args[])
    {
        Node root = null;
        root = new Node(1);
        root.left = new Node(2);
        root.right = new Node(3);
        root.left.left = new Node(4);
        root.right.left = new Node(2);
        root.right.left.left = new Node(4);
        root.right.right = new Node(4);
        printAllDups(root);
    }
}
// This code is contributed by Sumit Ghosh


Python3




# Python3 program to find averages of
# all levels in a binary tree.
 
# Helper function that allocates a
# new node with the given data and
# None left and right pointers.
class newNode:
    def __init__(self, data):
        self.data = data
        self.left = self.right = None
 
def inorder(node, m):
    if (not node):
        return ""
 
    Str = "("
    Str += inorder(node.left, m)
    Str += str(node.data)
    Str += inorder(node.right, m)
    Str += ")"
 
    # Subtree already present (Note that
    # we use unordered_map instead of
    # unordered_set because we want to print
    # multiple duplicates only once, consider
    # example of 4 in above subtree, it
    # should be printed only once.
    if (Str in m and m[Str] == 1):
        print(node.data, end = " ")
    if Str in m:
        m[Str] += 1
    else:
        m[Str] = 1
 
    return Str
 
# Wrapper over inorder()
def printAllDups(root):
    m = {}
    inorder(root, m)
 
# Driver code
if __name__ == '__main__':
    root = None
    root = newNode(1)
    root.left = newNode(2)
    root.right = newNode(3)
    root.left.left = newNode(4)
    root.right.left = newNode(2)
    root.right.left.left = newNode(4)
    root.right.right = newNode(4)
    printAllDups(root)
 
# This code is contributed by PranchalK


C#




// A C# program to find all duplicate subtrees
// in a binary tree.
using System;
using System.Collections.Generic;
 
class GFG
{
 
    /* A binary tree node has data, pointer to
    left child and a pointer to right child */
    static Dictionary<String,
                      int> m = new Dictionary<String,
                                              int>();
    public class Node
    {
        public int data;
        public Node left;
        public Node right;
        public Node(int data)
        {
            this.data = data;
            left = null;
            right = null;
        }
    }
     
    static String inorder(Node node)
    {
        if (node == null)
            return "";
     
        String str = "(";
        str += inorder(node.left);
        str += (node.data).ToString();
        str += inorder(node.right);
        str += ")";
     
        // Subtree already present (Note that we use
        // HashMap instead of HashSet
        // because we want to print multiple duplicates
        // only once, consider example of 4 in above
        // subtree, it should be printed only once.    
        if (m.ContainsKey(str) && m[str] == 1 )
            Console.Write(node.data + " ");
     
        if (m.ContainsKey(str))
            m[str] = m[str] + 1;
        else
            m.Add(str, 1);
         
        return str;
    }
     
    // Wrapper over inorder()
    static void printAllDups(Node root)
    {
        m = new Dictionary<String, int>();
        inorder(root);
    }
     
    // Driver code
    public static void Main(String []args)
    {
        Node root = null;
        root = new Node(1);
        root.left = new Node(2);
        root.right = new Node(3);
        root.left.left = new Node(4);
        root.right.left = new Node(2);
        root.right.left.left = new Node(4);
        root.right.right = new Node(4);
        printAllDups(root);
    }
}
 
// This code is contributed by Princi Singh


Javascript




<script>
    // A javascript program to find all duplicate subtrees
    // in a binary tree.
     
    class Node
    {
        constructor(data) {
           this.left = null;
           this.right = null;
           this.data = data;
        }
    }
     
    /* A binary tree node has data, pointer to
    left child and a pointer to right child */
    let m;
     
    function inorder(node)
    {
        if (node == null)
            return "";
       
        let str = "(";
        str += inorder(node.left);
        str += toString(node.data);
        str += inorder(node.right);
        str += ")";
       
        // Subtree already present (Note that we use
        // HashMap instead of HashSet
        // because we want to print multiple duplicates
        // only once, consider example of 4 in above
        // subtree, it should be printed only once.     
        if (m.get(str) != null && m.get(str)==1 )
            document.write( node.data + " ");
       
        if (m.has(str))
            m.set(str, m.get(str) + 1);
        else
            m.set(str, 1);
          
         
        return str;
    }
       
    // Wrapper over inorder()
    function printAllDups(root)
    {
        m = new Map();
        inorder(root);
    }
     
    let root = null;
    root = new Node(1);
    root.left = new Node(2);
    root.right = new Node(3);
    root.left.left = new Node(4);
    root.right.left = new Node(2);
    root.right.left.left = new Node(4);
    root.right.right = new Node(4);
    printAllDups(root);
    
   // This code is contributed by suresh07.
</script>


Output

4 2 

Time Complexity: O(N^2)  Since string copying takes O(n) extra time.
Auxiliary Space: O(N^2) Since we are hashing a string for each node and length of this string can be of the order 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
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                           /
9 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
Count of SubTrees with digit sum of all nodes equals to X
Given a binary tree consisting of N nodes and a positive integer X. The task is to count the number of subtrees with the digit sum of nodes equals X. Examples: Input: N = 7, X = 29 10 / \ 2 3 / \ / \ 9 3 4 7 Output: 2Explanation: The whole binary tree is a subtree with digit sum equals 29. Input: N = 7, X = 14 10 / \ 2 3 / \ / \ 9 3 4 7 Output: 2 A
11 min read
Replace each node in given N-ary Tree with sum of all its subtrees
Given an N-ary tree. The task is to replace the values of each node with the sum of all its subtrees and the node itself. Examples Input: 1 / | \ 2 3 4 / \ \ 5 6 7Output: Initial Pre-order Traversal: 1 2 5 6 7 3 4 Final Pre-order Traversal: 28 20 5 6 7 3 4 Explanation: Value of each node is replaced by the sum of all its subtrees and the node itsel
8 min read
Calculate number of nodes in all subtrees | Using DFS
Given a tree in the form of adjacency list we have to calculate the number of nodes in the subtree of each node while calculating the number of nodes in the subtree of a particular node that node will also be added as a node in subtree hence the number of nodes in subtree of leaves is 1. Examples: Input : Consider the Graph mentioned below: Output
8 min read
Find Count of Single Valued Subtrees
Given a binary tree, write a program to count the number of Single Valued Subtrees. A Single Valued Subtree is one in which all the nodes have same value. Expected time complexity is O(n). Example: Input: root of below tree 5 / \ 1 5 / \ \ 5 5 5Output: 4There are 4 subtrees with single values.Input: root of below tree 5 / \ 4 5 / \ \ 4 4 5 Output:
15+ min read
Find largest subtree having identical left and right subtrees
Given a binary tree, find the largest subtree having identical left and right subtree. Expected complexity is O(n). For example, Input: 50 / \ 10 60 / \ / \ 5 20 70 70 / \ / \ 65 80 65 80 Output: Largest subtree is rooted at node 60 A simple solution is to consider every node, recursively check if left and right subtrees are identical using the app
12 min read
Subtrees formed after bursting nodes
You are given an n-ary tree with a special property: If we burst a random node of the tree, this node along with its immediate parents up to the root vanishes. The tree has N nodes and nodes are numbered from 1 to N. The root is always at 1. Given a sequence of queries denoting the number of the node we start bursting, the problem is to find the nu
10 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
Article Tags :
Practice Tags :
three90RightbarBannerImg