{x}
blog image

Find Root of N-Ary Tree

Solution Explanation:

This problem leverages the properties of bitwise XOR (^) to efficiently find the root of an N-ary tree. The core idea is that XORing all node values in a tree, and then XORing all the children nodes' values, will leave the root node's value as the only one remaining. This is because:

  • XOR is its own inverse: a ^ a == 0.
  • XOR is commutative and associative: The order of XOR operations doesn't matter.

Algorithm:

  1. XOR all node values: Iterate through the tree array and XOR each node's val with a running XOR sum (x).

  2. XOR children values: For each node, iterate through its children and XOR their vals with x. This cancels out the children's values.

  3. Find the root: After the loop, x will hold the value of the root node because all other nodes' values will have cancelled out due to the XOR operations. Iterate through the tree again and find the node whose value is equal to x. This is the root node.

Time Complexity: O(N), where N is the number of nodes in the tree. We iterate through the tree twice: once to XOR the values and once to find the root. The overall time complexity is linear in terms of the number of nodes.

Space Complexity: O(1). We are using only a constant amount of extra space to store the variable x. We are not creating additional data structures proportional to the size of the input.

Code Explanation (Python):

class Solution:
    def findRoot(self, tree: List['Node']) -> 'Node':
        x = 0  # Initialize XOR sum
        for node in tree:
            x ^= node.val # XOR node value
            for child in node.children:
                x ^= child.val # XOR children values
        return next(node for node in tree if node.val == x) # Find the node with the remaining value (root)
 

The Python code directly implements the algorithm described above. The next() function with a generator expression efficiently finds the node with the matching value. If no such node exists, a StopIteration exception is raised (but is handled implicitly in this case).

Code Explanation (Java):

class Solution {
    public Node findRoot(List<Node> tree) {
        int x = 0;
        for (Node node : tree) {
            x ^= node.val;
            for (Node child : node.children) {
                x ^= child.val;
            }
        }
        for (int i = 0;; ++i) { // Infinite loop, but guaranteed to terminate
            if (tree.get(i).val == x) {
                return tree.get(i);
            }
        }
    }
}

The Java code is functionally equivalent to the Python code, using a for-each loop for iteration and directly accessing elements of the List. The for(;;) loop iterates until the node with the matching value is found, which will always happen as the root is guaranteed to be in the list.

Similar logic applies to the C++, Go, and TypeScript implementations – they all follow the same algorithmic approach with minor syntactic differences.