Find Root of N-Ary Tree
In this page, we will solve the Find Root of N-Ary Tree problem using different approaches: counting the degree of each node and a hash set approach. We will provide the implementation of the solution in JavaScript, TypeScript, Python, Java, C++, and more.
Problem Description​
You are given all the nodes of an N-ary tree as an array of Node objects, where each node has a unique value.
Return the root of the N-ary tree.
Each Node object has the following properties:
int val: the value of the node.List<Node> children: the list of children of the node.
Examples​
Example 1:
Input: 
Input: [1, null, 3, 2, 4, null, 5, 6]
Output: 1
Explanation: The root of the tree is 1.
Example 2:
Input: 
Input: [1, null, 2, 3, 4, 5, null, null, 6, 7, null, 8, null, 9, 10, null, null, 11, null, 12, null, 13, null, null, 14]
Output: 1
Explanation: The root of the tree is 1.
Constraints​
- The total number of nodes is between 
[1, 5 * 10^4]. 
Solution for Find Root of N-Ary Tree​
Intuition and Approach​
To find the root of an N-ary tree, we can use the following approaches:
- Counting the Degree: In this approach, we count the in-degrees (number of times a node appears as a child) of all nodes. The node with an in-degree of zero is the root.
 - Hash Set: We use a hash set to keep track of all nodes and another hash set for all children nodes. The difference between these sets will give us the root node.
 
- Counting Degree
 - Hash Set
 
Approach 1: Counting the Degree​
Implementation​
function findRootOfNAryTree() { class Node { constructor(val) { this.val = val; this.children = []; } } const nodes = [ new Node(1), new Node(2), new Node(3), new Node(4), new Node(5), new Node(6) ]; nodes[0].children = [nodes[1], nodes[2], nodes[3]]; nodes[1].children = [nodes[4], nodes[5]]; const findRoot = function(treeNodes) { const inDegree = new Map(); for (const node of treeNodes) { if (!inDegree.has(node)) { inDegree.set(node, 0); } for (const child of node.children) { inDegree.set(child, (inDegree.get(child) || 0) + 1); } } for (const [node, degree] of inDegree) { if (degree === 0) return node; } return null; }; const root = findRoot(nodes); return ( <div> <p> <b>Input:</b> {JSON.stringify(nodes.map(node => node.val))} </p> <p> <b>Output:</b> {root ? root.val : null} </p> </div> ); }
Code in Different Languages​
- JavaScript
 - TypeScript
 - Python
 - Java
 - C++
 
 function findRoot(treeNodes) {
   const inDegree = new Map();
   for (const node of treeNodes) {
     if (!inDegree.has(node)) {
       inDegree.set(node, 0);
     }
     for (const child of node.children) {
       inDegree.set(child, (inDegree.get(child) || 0) + 1);
     }
   }
   for (const [node, degree] of inDegree) {
     if (degree === 0) return node;
   }
   return null;
 }
 function findRoot(treeNodes: Node[]): Node | null {
   const inDegree = new Map<Node, number>();
   for (const node of treeNodes) {
     if (!inDegree.has(node)) {
       inDegree.set(node, 0);
     }
     for (const child of node.children) {
       inDegree.set(child, (inDegree.get(child) || 0) + 1);
     }
   }
   for (const [node, degree] of inDegree) {
     if (degree === 0) return node;
   }
   return null;
 }
 class Node:
     def __init__(self, val=None, children=None):
         self.val = val
         self.children = children if children is not None else []
 class Solution:
     def findRoot(self, tree: List['Node']) -> 'Node':
         in_degree = {node: 0 for node in tree}
         for node in tree:
             for child in node.children:
                 in_degree[child] += 1
         for node, degree in in_degree.items():
             if degree == 0:
                 return node
         return None
 import java.util.*;
 class Node {
     public int val;
     public List<Node> children;
     public Node() {}
     public Node(int val) {
         this.val = val;
     }
     public Node(int val, List<Node> children) {
         this.val = val;
         this.children = children;
     }
 }
 class Solution {
     public Node findRoot(List<Node> tree) {
         Map<Node, Integer> inDegree = new HashMap<>();
         for (Node node : tree) {
             inDegree.putIfAbsent(node, 0);
             for (Node child : node.children) {
                 inDegree.put(child, inDegree.getOrDefault(child, 0) + 1);
             }
         }
         for (Map.Entry<Node, Integer> entry : inDegree.entrySet()) {
             if (entry.getValue() == 0) {
                 return entry.getKey();
             }
         }
         return null;
     }
 }
 #include <vector>
 #include <unordered_map>
 using namespace std;
 class Node {
 public:
     int val;
     vector<Node*> children;
     Node() {}
     Node(int _val) {
         val = _val;
     }
     Node(int _val, vector<Node*> _children) {
         val = _val;
         children = _children;
     }
 };
 class Solution {
 public:
     Node* findRoot(vector<Node*> tree) {
         unordered_map<Node*, int> inDegree;
         for (Node* node : tree) {
             if (inDegree.find(node) == inDegree.end()) {
                 inDegree[node] = 0;
             }
             for (Node* child : node->children) {
                 inDegree[child]++;
             }
         }
         for (auto& entry : inDegree) {
             if (entry.second == 0) {
                 return entry.first;
             }
         }
         return nullptr;
     }
 };
Complexity Analysis​
- Time Complexity: , where 
Nis the number of nodes in the tree. - Space Complexity: , for storing the in-degree map.
 
Approach 2: Hash Set​
Implementation​
function findRootOfNAryTree() { class Node { constructor(val) { this.val = val; this.children = []; } } const nodes = [ new Node(1), new Node(2), new Node(3), new Node(4), new Node(5), new Node(6) ]; nodes[0].children = [nodes[1], nodes[2], nodes[3]]; nodes[1].children = [nodes[4], nodes[5]]; const findRoot = function(treeNodes) { const allNodes = new Set(treeNodes); const childrenNodes = new Set(); for (const node of treeNodes) { for (const child of node.children) { childrenNodes.add(child); } } for (const node of treeNodes) { if (!childrenNodes.has(node)) { return node; } } return null; }; const root = findRoot(nodes); return ( <div> <p> <b>Input:</b> {JSON.stringify(nodes.map(node => node.val))} </p> <p> <b>Output:</b> {root ? root.val : null} </p> </div> ); }
Code in Different Languages​
- JavaScript
 - TypeScript
 - Python
 - Java
 - C++
 
 function findRoot(treeNodes) {
   const allNodes = new Set(treeNodes);
   const childrenNodes = new Set();
   for (const node of treeNodes) {
     for (const child of node.children) {
       childrenNodes.add(child);
     }
   }
   for (const node of treeNodes) {
     if (!childrenNodes.has(node)) {
       return node;
     }
   }
   return null;
 }
 function findRoot(treeNodes: Node[]): Node | null {
   const allNodes = new Set(treeNodes);
   const childrenNodes = new Set<Node>();
   for (const node of treeNodes) {
     for (const child of node.children) {
       childrenNodes.add(child);
     }
   }
   for (const node of treeNodes) {
     if (!childrenNodes.has(node)) {
       return node;
     }
   }
   return null;
 }
 class Node:
     def __init__(self, val=None, children=None):
         self.val = val
         self.children = children if children is not None else []
 class Solution:
     def findRoot(self, tree: List['Node']) -> 'Node':
         all_nodes = set(tree)
         children_nodes = set()
         for node in tree:
             for child in node.children:
                 children_nodes.add(child)
         for node in tree:
             if node not in children_nodes:
                 return node
         return None
 import java.util.*;
 class Node {
     public int val;
     public List<Node> children;
     public Node() {}
     public Node(int val) {
         this.val = val;
     }
     public Node(int val, List<Node> children) {
         this.val = val;
         this.children = children;
     }
 }
 class Solution {
     public Node findRoot(List<Node> tree) {
         Set<Node> allNodes = new HashSet<>(tree);
         Set<Node> childrenNodes = new HashSet<>();
         for (Node node : tree) {
             for (Node child : node.children) {
                 childrenNodes.add(child);
             }
         }
         for (Node node : tree) {
             if (!childrenNodes.contains(node)) {
                 return node;
             }
         }
         return null;
     }
 }
 #include <vector>
 #include <unordered_set>
 using namespace std;
 class Node {
 public:
     int val;
     vector<Node*> children;
     Node() {}
     Node(int _val) {
         val = _val;
     }
     Node(int _val, vector<Node*> _children) {
         val = _val;
         children = _children;
     }
 };
 class Solution {
 public:
     Node* findRoot(vector<Node*> tree) {
         unordered_set<Node*> allNodes(tree.begin(), tree.end());
         unordered_set<Node*> childrenNodes;
         for (Node* node : tree) {
             for (Node* child : node->children) {
                 childrenNodes.insert(child);
             }
         }
         for (Node* node : tree) {
             if (childrenNodes.find(node) == childrenNodes.end()) {
                 return node;
             }
         }
         return nullptr;
     }
 };
Complexity Analysis​
- Time Complexity: , where 
Nis the number of nodes in the tree. - Space Complexity: , for storing the sets of all nodes and children nodes.
 
By using both counting the degree and hash set approaches, we can efficiently find the root of an N-ary tree. The choice between the two approaches depends on the specific requirements and constraints of the problem.
References​
- LeetCode Problem: Find Root of N-Ary Tree
 - Solution Link: Find Root of N-Ary Tree Solution on LeetCode
 - Authors LeetCode Profile: Manish Kumar Gupta