Given an array representing the parent-child relationship in a binary tree, find the tree’s height without building it. The parent-child relationship is defined by (A[i], i) for every index i in array A. The root node’s value will be i if -1 is present at index i in the array.

The depth of a “node” is the total number of edges from the node to the tree’s root node. The root is the only node whose depth is 0.

The height of a “node” is the total number of edges on the longest path from the node to a leaf. The height of a “tree” would be the height of its root node, or equivalently, the depth of its deepest node. A leaf node will have a height of 0.

 
For example,

Parent: [-1, 0, 0, 1, 2, 2, 4, 4]
Index:  [0, 1, 2, 3, 4, 5, 6, 7]
 
  • -1 is present at index 0, which implies that the binary tree root is node 0.
  • 0 is present at index 1 and 2, which implies that the left and right children of node 0 are 1 and 2.
  • 1 is present at index 3, which implies that the left or the right child of node 1 is 3.
  • 2 is present at index 4 and 5, which implies that the left and right children of node 2 are 4 and 5.
  • 4 is present at index 6 and 7, which implies that the left and right children of node 4 are 6 and 7.

The corresponding binary tree is:

Build Binary Tree from Parent Array

Practice this problem

 
Related Post:

Build a binary tree from a parent array

 
A simple solution would be to construct the binary tree using the parent array, as demonstrated in the above post. After the tree is constructed, calculate its height. The time complexity of the above solution is O(n) and requires O(n) extra space, where n is the size of the parent array. However, as per problem constraints, the height should be calculated without building the tree.

 
The idea is to calculate the depth of every node using recursion and return the maximum depth found. Since the node’s depth is the total number of edges from the node to the root, we need to trace the node’s path to the root node using the parent-child relationship. We can do this by recursively traversing the parent array. The algorithm can be implemented as follows in C, Java, and Python:

C


Download  Run Code

Output:

The height of the binary tree is 3

Java


Download  Run Code

Output:

The height of the binary tree is 3

Python


Download  Run Code

Output:

The height of the binary tree is 3

The time complexity of the above solution is O(n2), where n is the total number of nodes in the binary tree. The auxiliary space required by the program is O(h) for the call stack, where h is the height of the tree.

 
Note that the findDepth() routine has an optimal substructure since it can be recursively broken down into smaller sub-routines, i.e., findDepth(i) = 1 + findDepth(parent[i]). It also exhibits overlapping subproblems since the same subproblem is solved over and over again.

We know that problems having optimal substructure and overlapping subproblems can be solved using dynamic programming. Following is the dynamic programming implementation in C, Java, and Python, where subproblem solutions are memoized rather than computed repeatedly. The solution uses an auxiliary array to store the depth of each node.

C


Download  Run Code

Output:

The height of the binary tree is 3

Java


Download  Run Code

Output:

The height of the binary tree is 3

Python


Download  Run Code

Output:

The height of the binary tree is 3

The time complexity of the above solution is O(n) since the depth of every node is evaluated only once. The additional space used by the program is O(n).

 
Here’s a bottom-up iterative version of the above top-down recursive solution in C, Java, and Python:

C


Download  Run Code

Output:

The height of the binary tree is 3

Java


Download  Run Code

Output:

The height of the binary tree is 3

Python


Download  Run Code

Output:

The height of the binary tree is 3

The time complexity of the above solution is O(n), and the auxiliary space used by the program is O(n).