Count the number of common ancestors of given K nodes in a N-ary Tree
Given an N-ary tree root and a list of K nodes, the task is to find the number of common ancestors of the given K nodes in the tree.
Example:
Input: root = 3
/ \
2 1
/ \ / | \
9 7 8 6 3
K = {7, 2, 9}
Output: 2
Explanation: The common ancestors of the nodes 7, 9 and 2 are 2 and 3Input: root = 2
\
1
\
0—4
/ | \
9 3 8
K = {9, 8, 3, 4, 0}
Output: 3
Approach: The given problem can be solved by using the post-order traversal. The idea is to find the lowest common ancestor of the K nodes then increment the count of ancestors for every node above it till the root is reached. Below steps can be followed to solve the problem:
- Add all the list nodes into a set
- Apply post-order traversal on the tree:
- Find the lowest common ancestor then start incrementing the value of the number of nodes at every recursive call
- Return the answer calculated
C++
// C++ implementation for the above approach #include<bits/stdc++.h> using namespace std; class Node { public : vector<Node*> children; int val; Node( int val) { this ->val = val; } }; // Function to find LCA and // count number of ancestors vector<Node*> CAcount(Node* root, set<Node*> st) { // If the current node // is a desired node if (st.count(root)) { vector<Node*> res(2, NULL); res[0] = root; res[1] = new Node(1); return res; } // If leaf node then return null if (root->children.size() == 0) { vector<Node*> res(2, NULL); return res; } // To count number of desired nodes // in the children branches int childCount = 0; // Initialize a node to return vector<Node*> ans(2, NULL); // Iterate through all children for ( auto child: root->children){ vector<Node*> res = CAcount(child, st); // Increment child count if // desired node is found if (res[0] != NULL) childCount++; // If first desired node is found if (childCount == 1 && ans[0] == NULL) { ans = res; } else if (childCount > 1) { ans[0] = root; ans[1] = new Node(1); return ans; } } // If LCA found below then increment // number of common ancestors if (ans[0] != NULL) ans[1]->val++; // Return the answer return ans; } // Function to find the number // of common ancestors in a tree int numberOfAncestors(Node* root, vector<Node*> nodes) { // Initialize a set set<Node*> st; // Iterate the list of nodes // and add them in a set for ( auto curr: nodes){ st.insert(curr); } // Find LCA and return // number of ancestors return CAcount(root, st)[1]->val; } // Driver code int main() { // Initialize the tree Node* zero = new Node(0); Node* one = new Node(1); Node* two = new Node(2); Node* three = new Node(3); Node* four = new Node(4); Node* five = new Node(5); Node* six = new Node(6); Node* seven = new Node(7); zero->children.push_back(one); zero->children.push_back(two); zero->children.push_back(three); one->children.push_back(four); one->children.push_back(five); five->children.push_back(six); five->children.push_back(seven); // List of nodes whose // ancestors are to be found vector<Node*> nodes; nodes.push_back(four); nodes.push_back(six); nodes.push_back(seven); // Call the function // and print the result cout << numberOfAncestors(zero, nodes) << endl; return 0; } // The code is contributed by Nidhi goel. |
Java
// Java implementation for the above approach import java.io.*; import java.util.*; class GFG { static class Node { List<Node> children; int val; // constructor public Node( int val) { children = new ArrayList<>(); this .val = val; } } // Function to find the number // of common ancestors in a tree public static int numberOfAncestors( Node root, List<Node> nodes) { // Initialize a set Set<Node> set = new HashSet<>(); // Iterate the list of nodes // and add them in a set for (Node curr : nodes) { set.add(curr); } // Find LCA and return // number of ancestors return CAcount(root, set)[ 1 ].val; } // Function to find LCA and // count number of ancestors public static Node[] CAcount( Node root, Set<Node> set) { // If the current node // is a desired node if (set.contains(root)) { Node[] res = new Node[ 2 ]; res[ 0 ] = root; res[ 1 ] = new Node( 1 ); return res; } // If leaf node then return null if (root.children.size() == 0 ) { return new Node[ 2 ]; } // To count number of desired nodes // in the children branches int childCount = 0 ; // Initialize a node to return Node[] ans = new Node[ 2 ]; // Iterate through all children for (Node child : root.children) { Node[] res = CAcount(child, set); // Increment child count if // desired node is found if (res[ 0 ] != null ) childCount++; // If first desired node is found if (childCount == 1 && ans[ 0 ] == null ) { ans = res; } else if (childCount > 1 ) { ans[ 0 ] = root; ans[ 1 ] = new Node( 1 ); return ans; } } // If LCA found below then increment // number of common ancestors if (ans[ 0 ] != null ) ans[ 1 ].val++; // Return the answer return ans; } // Driver code public static void main(String[] args) { // Initialize the tree Node zero = new Node( 0 ); Node one = new Node( 1 ); Node two = new Node( 2 ); Node three = new Node( 3 ); Node four = new Node( 4 ); Node five = new Node( 5 ); Node six = new Node( 6 ); Node seven = new Node( 7 ); zero.children.add(one); zero.children.add(two); zero.children.add(three); one.children.add(four); one.children.add(five); five.children.add(six); five.children.add(seven); // List of nodes whose // ancestors are to be found List<Node> nodes = new ArrayList<>(); nodes.add(four); nodes.add(six); nodes.add(seven); // Call the function // and print the result System.out.println( numberOfAncestors(zero, nodes)); } } |
Python3
# Python3 implementation for the above approach class Node: def __init__( self , val): self .children = [] self .val = val # Function to find the number # of common ancestors in a tree def number_of_ancestors(root, nodes): set_nodes = set (nodes) # Find LCA and return # number of ancestors return CAcount(root, set_nodes)[ 1 ].val # Function to find LCA and # count number of ancestors def CAcount(root, set_nodes): if root in set_nodes: res = [root, Node( 1 )] return res if not root.children: return [ None , None ] # To count number of desired nodes # in the children branches child_count = 0 ans = [ None , None ] for child in root.children: res = CAcount(child, set_nodes) # Increment child count if # desired node is found if res[ 0 ] is not None : child_count + = 1 if child_count = = 1 and ans[ 0 ] is None : ans = res elif child_count > 1 : ans = [root, Node( 1 )] return ans # If LCA found below then increment # number of common ancestors if ans[ 0 ] is not None : ans[ 1 ].val + = 1 return ans # Initialize the tree zero = Node( 0 ) one = Node( 1 ) two = Node( 2 ) three = Node( 3 ) four = Node( 4 ) five = Node( 5 ) six = Node( 6 ) seven = Node( 7 ) zero.children.append(one) zero.children.append(two) zero.children.append(three) one.children.append(four) one.children.append(five) five.children.append(six) five.children.append(seven) nodes = [four, six, seven] print (number_of_ancestors(zero, nodes)) # This code is contributed by Potta Lokesh |
C#
// C# implementation for the above approach using System; using System.Collections.Generic; public class GFG { class Node { public List<Node> children; public int val; // constructor public Node( int val) { children = new List<Node>(); this .val = val; } } // Function to find the number // of common ancestors in a tree static int numberOfAncestors( Node root, List<Node> nodes) { // Initialize a set HashSet<Node> set = new HashSet<Node>(); // Iterate the list of nodes // and add them in a set foreach (Node curr in nodes) { set .Add(curr); } // Find LCA and return // number of ancestors return CAcount(root, set )[1].val; } // Function to find LCA and // count number of ancestors static Node[] CAcount( Node root, HashSet<Node> set ) { // If the current node // is a desired node if ( set .Contains(root)) { Node[] res = new Node[2]; res[0] = root; res[1] = new Node(1); return res; } // If leaf node then return null if (root.children.Count == 0) { return new Node[2]; } // To count number of desired nodes // in the children branches int childCount = 0; // Initialize a node to return Node[] ans = new Node[2]; // Iterate through all children foreach (Node child in root.children) { Node[] res = CAcount(child, set ); // Increment child count if // desired node is found if (res[0] != null ) childCount++; // If first desired node is found if (childCount == 1 && ans[0] == null ) { ans = res; } else if (childCount > 1) { ans[0] = root; ans[1] = new Node(1); return ans; } } // If LCA found below then increment // number of common ancestors if (ans[0] != null ) ans[1].val++; // Return the answer return ans; } // Driver code public static void Main(String[] args) { // Initialize the tree Node zero = new Node(0); Node one = new Node(1); Node two = new Node(2); Node three = new Node(3); Node four = new Node(4); Node five = new Node(5); Node six = new Node(6); Node seven = new Node(7); zero.children.Add(one); zero.children.Add(two); zero.children.Add(three); one.children.Add(four); one.children.Add(five); five.children.Add(six); five.children.Add(seven); // List of nodes whose // ancestors are to be found List<Node> nodes = new List<Node>(); nodes.Add(four); nodes.Add(six); nodes.Add(seven); // Call the function // and print the result Console.WriteLine( numberOfAncestors(zero, nodes)); } } // This code is contributed by shikhasingrajput |
Javascript
<script> // Javascript implementation for the above approach class Node { // constructor constructor(val) { this .children = new Array(); this .val = val; } } // Function to find the number // of common ancestors in a tree function numberOfAncestors(root, nodes) { // Initialize a set let set = new Set(); // Iterate the list of nodes // and add them in a set for (curr of nodes) { set.add(curr); } // Find LCA and return // number of ancestors return CAcount(root, set)[1].val; } // Function to find LCA and // count number of ancestors function CAcount(root, set) { // If the current node // is a desired node if (set.has(root)) { let res = new Node(2); res[0] = root; res[1] = new Node(1); return res; } // If leaf node then return null if (root.children.length == 0) { return new Node(2); } // To count number of desired nodes // in the children branches let childCount = 0; // Initialize a node to return let ans = new Node(2); // Iterate through all children for (child of root.children) { let res = CAcount(child, set); // Increment child count if // desired node is found if (res[0] != null ) childCount++; // If first desired node is found if (childCount == 1 && ans[0] == null ) { ans = res; } else if (childCount > 1) { ans[0] = root; ans[1] = new Node(1); return ans; } } // If LCA found below then increment // number of common ancestors if (ans[0] != null ) ans[1].val++; // Return the answer return ans; } // Driver code // Initialize the tree let zero = new Node(0); let one = new Node(1); let two = new Node(2); let three = new Node(3); let four = new Node(4); let five = new Node(5); let six = new Node(6); let seven = new Node(7); zero.children.push(one); zero.children.push(two); zero.children.push(three); one.children.push(four); one.children.push(five); five.children.push(six); five.children.push(seven); // List of nodes whose // ancestors are to be found let nodes = new Array(); nodes.push(four); nodes.push(six); nodes.push(seven); // Call the function // and print the result document.write(numberOfAncestors(zero, nodes)); // This code is contributed by saurabh_jaiswal. </script> |
2
Time Complexity: O(N), where N is the number of nodes in the tree
Auxiliary Space: O(H), H is the height of the tree
Please Login to comment...