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 N Output: 2 Explanation: [4], [3] are duplicate subtree.
Structure of the tree
Input: 1 N 2 3 N 4 5 6 N N N N Output: 0 Explanation: No duplicate subtree found.
Approach: This problem can be solved using in-order traversal of the Tree.
The idea is to store the inorder traversal of every vertex in the form of string and put this string in a map.
So after inorder traversal of the complete tree we will have all distinct strings in map along with their frequencies. Now we can simply iterate over the map and check if frequency of the string is greater than 1, then more than 1 tree have same structure. So increment the answer.
Follow the below steps to implement the idea:
First of all, declare an unordered map, and store the inorder traversal of the tree in it.
For every vertex, store the inorder traversal for its subtree in the map.
After that, just check the frequency of the strings.
If it is greater than 1, then consider it. Otherwise not.
Below is the implementation of the above approach:
C++
// C++ code to implement the approach#include<bits/stdc++.h>usingnamespacestd;// Structure of a tree nodeclassNode{public:intdata;vector<Node*>children;Node(intval){data=val;}};// Function to run dfsstringdfs(Node*root,unordered_map<string,int>&f){// Base conditionif(root==0)return"";strings="(";s+=to_string(root->data);// Dfs call for all childrenfor(autochild:root->children){s+=dfs(child,f);}s+=')';f[s]++;// Return answer stringreturns;}// Function to count number of duplicate substringsintduplicateSubtreeNaryTree(Node*root){// Declare a mapunordered_map<string,int>f;// DFS calldfs(root,f);intans=0;// Loop for traversing the mapfor(autop:f)if(p.second>1)ans++;// Return the count of duplicate subtreesreturnans;}// Driver codeintmain(){// Building a treeNode*root=newNode(1);root->children.push_back(newNode(2));root->children.push_back(newNode(2));root->children.push_back(newNode(3));root->children[0]->children.push_back(newNode(4));root->children[1]->children.push_back(newNode(4));root->children[1]->children.push_back(newNode(4));root->children[1]->children.push_back(newNode(3));// Function callcout<<duplicateSubtreeNaryTree(root);return0;}
Java
importjava.util.*;classNode{publicintdata;publicList<Node>children;publicNode(intval){data=val;children=newArrayList<Node>();}}publicclassMain{publicstaticStringdfs(Noderoot,Map<String,Integer>f){// Base conditionif(root==null)return"";Strings="("+Integer.toString(root.data);// Dfs call for all childrenfor(Nodechild:root.children){s+=dfs(child,f);}s+=')';f.put(s,f.getOrDefault(s,0)+1);returns;}publicstaticintduplicateSubtreeNaryTree(Noderoot){Map<String,Integer>f=newHashMap<>();dfs(root,f);intans=0;for(Map.Entry<String,Integer>entry:f.entrySet()){if(entry.getValue()>1)ans++;}returnans;}publicstaticvoidmain(String[]args){Noderoot=newNode(1);root.children.add(newNode(2));root.children.add(newNode(2));root.children.add(newNode(3));root.children.get(0).children.add(newNode(4));root.children.get(1).children.add(newNode(4));root.children.get(1).children.add(newNode(4));root.children.get(1).children.add(newNode(3));System.out.println(duplicateSubtreeNaryTree(root));}}
Python3
classNode:def__init__(self,val):self.data=valself.children=[]# Function to run dfsdefdfs(root,f):# Base conditionifroot==None:return""s="("s+=str(root.data)# Dfs call for all childrenforchildinroot.children:s+=dfs(child,f)s+=')'ifsinf:f[s]+=1else:f[s]=1# Return answer stringreturns# Function to count number of duplicate substringsdefduplicateSubtreeNaryTree(root):# Declare a mapf={}# DFS calldfs(root,f)ans=0# Loop for traversing the mapforpinf:iff[p]>1:ans+=1# Return the count of duplicate subtreesreturnans# Building a treeroot=Node(1)root.children.append(Node(2))root.children.append(Node(2))root.children.append(Node(3))root.children[0].children.append(Node(4))root.children[1].children.append(Node(4))root.children[1].children.append(Node(4))root.children[1].children.append(Node(3))# Function callprint(duplicateSubtreeNaryTree(root))
C#
// C# code to implement the approachusingSystem;usingSystem.Collections.Generic;usingSystem.Linq;// Structure of a tree nodeclassNode{publicintdata;publicList<Node>children;publicNode(intval){data=val;children=newList<Node>();}}publicclassGFG{// Function to run dfsstaticstringdfs(Noderoot,Dictionary<string,int>f){// Base conditionif(root==null)return"";strings="(";s+=root.data.ToString();// Dfs call for all childrenforeach(varchildinroot.children){s+=dfs(child,f);}s+=')';if(f.ContainsKey(s))f[s]++;elsef.Add(s,1);// Return answer stringreturns;}// Function to count number of duplicate substringsstaticintduplicateSubtreeNaryTree(Noderoot){// Declare a mapDictionary<string,int>f=newDictionary<string,int>();// DFS calldfs(root,f);intans=0;// Loop for traversing the mapforeach(varpinf){if(p.Value>1)ans++;}// Return the count of duplicate subtreesreturnans;}staticpublicvoidMain(){// Code// Building a treeNoderoot=newNode(1);root.children.Add(newNode(2));root.children.Add(newNode(2));root.children.Add(newNode(3));root.children[0].children.Add(newNode(4));root.children[1].children.Add(newNode(4));root.children[1].children.Add(newNode(4));root.children[1].children.Add(newNode(3));// Function callConsole.WriteLine(duplicateSubtreeNaryTree(root));}}// This code is contributed by lokeshmvs21.
JavaScript
// JavaScript code for the above approach// Structure of a tree nodeclassNode{constructor(val){this.data=val;this.children=[];}};// Function to run dfsfunctiondfs(root,f){// Base conditionif(root==0)return"";lets="(";s+=(root.data).toString();// Dfs call for all childrenfor(letchildofroot.children){s+=dfs(child,f);}s+=')';if(f.has(s)){f.set(s,f.get(s)+1)}else{f.set(s,1);}// Return answer stringreturns;}// Function to count number of duplicate substringsfunctionduplicateSubtreeNaryTree(root){// Declare a mapletf=newMap();// DFS calldfs(root,f);letans=0;// Loop for traversing the mapfor(let[key,val]off)if(val>1)ans++;// Return the count of duplicate subtreesreturnans;}// Driver code// Building a treeletroot=newNode(1);root.children.push(newNode(2));root.children.push(newNode(2));root.children.push(newNode(3));root.children[0].children.push(newNode(4));root.children[1].children.push(newNode(4));root.children[1].children.push(newNode(4));root.children[1].children.push(newNode(3));// Function callconsole.log(duplicateSubtreeNaryTree(root));// This code is contributed by Potta Lokesh.
Output
2
Time Complexity: O(V) Auxiliary Space: O(V2) because we are storing string for each vertex and the max string length can be V