Click here to Skip to main content
15,890,378 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello. I am learning about different Data Structures from a course in Coursera and I am just a beginner.
I had one exercise which was for finding the maximum height or maximum depth of a tree(but not just for binary trees). But unfortunately, my code does not pass all the tests in the specified time but it works correctly.
Here is the exercise description:

Task. You are given a description of a rooted tree. Your task is to compute and output its height. Recall that the height of a (rooted) tree is the maximum depth of a node or the maximum distance from a leaf to the root. You are given an arbitrary tree, not necessarily a binary tree.
Input Format. The first line contains the number of nodes 𝑛. The second line contains 𝑛 integer numbers from −1 to 𝑛 − 1 — parents of nodes. If the 𝑖-th one of them (0 ≤ 𝑖 ≤ 𝑛 − 1) is −1, node 𝑖 is the root, otherwise it’s 0-based index of the parent of 𝑖-th node. It is guaranteed that there is exactly one root.
It is guaranteed that the input represents a tree.
Constraints. 1 ≤ 𝑛 ≤ 105.
Output Format. Output the height of the tree.



Sample 1.
Input:
5
4 -1 4 1 1

Output:
3

The input means that there are 5 nodes with numbers from 0 to 4, node 0 is a child of node 4, node 1 is the root, node 2 is a child of node 4, node 3 is a child of node 1, and node 4 is a child of node 1. To see this, let us write numbers of nodes from 0 to 4 in one line, and the numbers are given in the input in the second line underneath:
0 1 2 3 4
4 -1 4 1 1

Now we can see that node number 1 is the root because −1 corresponds to it in the second line.
Also, we know that nodes number 3 and number 4 are children of the root node 1. Also, we know that nodes number 0 and number 2 are children of node 4.

The height of this tree is 3 because the number of vertices on the path from root 1 to leaf 2 is 3.



Sample 2.
Input:
5
-1 0 4 0 3

Output:
4

Explanation:
The input means that there are 5 nodes with numbers from 0 to 4, node 0 is the root, node 1 is a child of node 0, node 2 is a child of node 4, node 3 is a child of node 0, and node 4 is a child of node 3. The height of this tree is 4 because the number of nodes on the path from root 0 to leaf 2 is 4.

What I have tried:

Here is my code:
C#
public long Solve(long nodeCount, long[] tree)
{
    // 
    long max_height = 0;
    for (long i = 0; i < nodeCount; i++)
    {
        long h = 0;
        long current = i;
        while (current != -1)
        {
            h++;
            current = tree[current];
        }
        max_height = Math.Max(h, max_height);
    }
    return max_height;
}


There is a total of 24 test cases for this exercise and my code shows "Time Limit error" after the 20th testcase.

I will be really grateful for any help.

Thanks.
Posted
Updated 11-Dec-21 9:16am
v3
Comments
PIEBALDconsult 27-Nov-21 10:50am    
You seem to have a lot of trouble with this, what have you learned in the past?

https://www.codeproject.com/Questions/5316432/How-can-I-make-my-code-better-and-decrease-the-tim
https://www.codeproject.com/Questions/5314051/How-can-I-decrease-the-time-which-is-used-in-this

The way you are solving it is inefficient: it's ok for tiny trees like your example, but it's useless for bigger trees as the execution time goes up exponentially. You need a linear - or one pass preferably - solution.

So think about the problem: you are treating it as a tree, and trying to traverse it as such. Do you need to?
The root node has a negative value, we are only interested in the height so we can throw away tree info if we want to, and we know the depth of a node if (and only if) the depth of it's parent is known - so can we use that to tell us the depth if the parent value is negative by replacing the actual parent by the parent count minus one?
So in your example
-1 0 4 0 3
becomes
-1 -2 -4 -2 -3
after two passes (and with a little effort secondary and so forth passes can be shorter)
The minimum value there is -4 (and you don't even need to search for that if you think about it) so the height of the tree is the absolute value of (-4 + 1) or "3".

Try it on paper and you'll see what I mean.
 
Share this answer
 
Comments
PIEBALDconsult 27-Nov-21 11:02am    
Wouldn't the height simply be the number of unique values?
Stick 'em in a Set and get the cardinality.
height = ( new HashSet ( { ... } ) ).Count ; or similar
OriginalGriff 27-Nov-21 11:18am    
Nope, because two branches can have equal height:
           List<int> items = new List<int> { -1, 0, 4, 0, 3, 1, 5  };
           int height = new HashSet<int>(items).Count;

Will give you 7.
       0
      / \
     1   3
    /     \
   5       4
  /         \
 6           2
OriginalGriff 27-Nov-21 11:20am    
But I had to think about it, and then try it out - so well done, good idea!
PIEBALDconsult 27-Nov-21 11:33am    
Yeah, me too.
  0
 /|\
1 2 3
| | |
4 5 6
Aylin Naebzadeh 27-Nov-21 12:07pm    
Sorry, but I did not get your solution. Actually, in this example, the max height becomes 4, not 3🤔. I mean I did not get how did you calculate this sequence:
-1 -2 -4 -2 -3
May you explain more about it?
If you're supposed to be learning to use data structures, then try using some.

The issue is that your implementation keeps throwing away the depths of nodes you revisit on another path.
Once you know the depth of a node, you need to store it for future use.

Here I'm using a Dictionary, but an array could be used to improve efficiency further.

C#
private static int
Height
(
  params int[] List
)
{
  int result = 0 ;

  System.Collections.Generic.Dictionary<int,int> height =
    new System.Collections.Generic.Dictionary<int,int> ( List.Length ) ;

  height [ -1 ] = 0 ;

  System.Collections.Generic.Stack<int> stack =
    new System.Collections.Generic.Stack<int>( List.Length ) ;

  for ( int i = 0 ; i < List.Length ; i++ )
  {
    if ( !height.ContainsKey ( i ) )
    {
      int node = i ;

      stack.Push ( node ) ;

      while ( stack.Count > 0 )
      {
        node = stack.Peek() ;

        int parent = List [ node ] ;

        if ( !height.ContainsKey ( parent ) )
        {
          stack.Push ( parent ) ;
        }
        else
        {
          int depth = height [ parent ] + 1 ;

          height [ node ] = depth ;

          stack.Pop() ;

          if ( result < depth )
          {
            result = depth ;
          }
        }
      }
    }
  }

  return ( result ) ;
}
 
Share this answer
 
Comments
Aylin Naebzadeh 12-Dec-21 13:13pm    
I would try your solution and debug it. Thanks.
Well, this is one of those "challenge" questions. The problem with the timeout is it weeds out solutions that are straightforward. The trick to beating the timeout is to completely rethink how you approach the problem.

One sure sign of a solution that's going to fail is having a loop nested inside another loop, like what you have.
 
Share this answer
 
Comments
PIEBALDconsult 27-Nov-21 12:07pm    
I get the feeling that the instructor is just trying to demonstrate his superiority over the students.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900