GeeksforGeeks » Trees specific questions

Construct tree from Ancestor Matrix

(13 posts)

Tags:

  1. kapil
    guest
    Posted 2 years ago #

    You are given a matrix M[n, n] for a tree with n nodes. In the given matrix M, M[i, j] is true iff node j is an ancestor of node i. Construct the tree from the given matrix.

    For example, you are given below matrix.

        1  2  3  4
    1  0  1  1  0
    
    2  0  0  1  0
    
    3  0  0  0  0
    
    4  0  1  1  0
    

    You need to construct the below tree. In the constructed tree ancestor relationship should be correct. A node can come on left or right of its parent as you cannot determine this information from the ancestor matrix

    Node numbers used in matrix are in bracket
                       5(3)
                      /
                    /
              10(2)
             /    \
           /        \
     12(1)    13(4)
    

    This question was asked in Amazon.

  2. crazyFrog
    Member
    Posted 2 years ago #

    Since we know that its a binary tree.
    Start by searching a row with all 0s , this is the root node, say its row number is 'r'
    The search for rows where only the 'r' column is 1 and rest other entries are 0s. There will be atmost 2 such rows (since its a binary tree), let their row numbers be 'a','b'. These will be the children of 'r'
    Repeat the same process recurrsively for 'a', and 'b', like for 'a', search for a row where only the ath column and rth column contains 1 rest 0s.
    Recurring in this way will build the tree from top to down

    Similarly the tree can be built bottom up just by considering the columns in place of rows, like now the column with all 0s will be leaf nodes and so on

  3. srini156
    guest
    Posted 1 year ago #

    Did anybody try implementing the approach by crazyFrog?

  4. vramanan
    guest
    Posted 1 year ago #

    constructTree(M)
    {
       root = findRoot(M);
    
       if (!root) {
          return NULL;
       }
    
       addToList(L, root);
    
       root->left = findChild(M, L, Ch);
       addToList(Ch, root->left);
    
        root->right = findChild(M, L, Ch);
    
        return root;
    }
    
    findRoot(M) {
    
       for (i=0; i<ROW; i++) {
          found = 1;
          for (j=0; j<COL; j++) {
              if (M[i][j]) {
                   found = 0;
                   break;
              }
              if (found)
                   return node[i];
        }
        return NULL;
    }
    
    findChild(M, L, Ch)
    {
       for (i=0; i<ROW; i++) {
          if (Ch.isPresent(node[i]) {
             continue;
          }
         found = 1;
        for (j=0; j<COL; j++) {
              if (L.isPresent(node[j]) {
                  contine;
              }
    
              if (M[i][j]) {
                  found = 0;
                  break;
              }
        }
        if (found) {
             return node[i];
         }
       }
         return NULL;
    }
    

    assuming node[] array has the mapping between node number and node. Without node[] array one can create a node, copy the data and return instead of the lookup.

  5. Sambasiva
    guest
    Posted 1 year ago #

  6. Ashish
    guest
    Posted 1 year ago #

    'Algo:
    1) Select row with all entries zero and make it as root.
    2)From all entries in matrix subtract 1 if its ancestor is that root.
    3) Now again search for the rows with all entries zero but dun select again the same row. You can mark all entries of that row as -1 if you have already selected that row.
    4)Continue till all rows become zero.'

  7. a
    guest
    Posted 11 months ago #

    1 1 1 0 0 0 1 0 1 1 0 1 0 0 0 0 0 1 0 0 0 1 1 1 0 0 0 1 0 1 0 1
    0 0 1 1 0 0 0 0 1 1 0 1 1 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1
    0 1 1 1 0 0 1 0 1 1 0 1 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1
    1 1 1 0 0 0 1 1 1 1 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1
    1 1 1 1 0 0 1 1 1 1 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1
    1 1 1 0 0 0 1 0 1 1 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1
    1 1 1 1 0 0 1 1 1 1 0 1 0 0 0 1 0 1 0 0 0 1 0 0 1 0 0 1 0 0 0 1
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
    1 1 1 0 0 0 1 0 1 1 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1
    1 1 1 1 0 0 1 0 1 1 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1
    1 1 1 1 0 0 1 0 1 1 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1
    1 1 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
    1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1
    1 0 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1
    1 1 1 1 0 0 1 0 1 1 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1
    0 1 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1
    0 0 1 0 0 0 1 0 1 1 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1
    0 1 1 0 0 0 0 0 1 1 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1

  8. mAc
    guest
    Posted 11 months ago #

    It can do:

    1. Let's define levels of the tree and their relationships in the ancestor matrix given.
    Number of 0s in the row of the matrix defines level of the node(=row_number).We can achieve the levels of each node in nxn time.

    2.Now, we know that there can be at most 'n' levels in the tree.So make an array of link lists of size 'n' with each index corresponds to the level of the tree.Store the node with level 'i' in the list 'i' along with their ancestors number.

    3. Now start traversing the link list from index 0.First index corresponds to root of the tree.

    4.Now we can construct our tree easily...The element in the list 'i' have to be a child of either of the elements in the list 'i-1'.Since we are storing all the ancestors number information in the link list itself we'll choose that ancestor whose level is 'i-1'.(for making this access fast we can keep an array to store the levels of every node).

    5.Repeat step 4 to construct whole tree.

    I hope it works...

  9. gauravsc
    guest
    Posted 11 months ago #

    @mac awesome reply :)

  10. Rahul
    guest
    Posted 10 months ago #

    @sambasiva can you explain the algorithm please..in detail clearly with each step ????

  11. Swagat
    guest
    Posted 9 months ago #

    @mac

    I think we can solve it without the linked list array also.

    Declare an array of size N, and store in it, the number of 1s in each row. The number of ones in a row is also the number of ancestors of that the particular node has. You should also observe that in a tree all ancestors are the nodes from the node to the root.

    Now sort the size N array.

    The lowest must be zero (0 means no ancestors - root).
    Similarly you'll find nodes with no of ancestors as 1, 2, 3... h-1 where h is the height of the final tree.
    Since it's given as a tree, no of nodes with "no of ancestors" = j will be at max twice the number of nodes with "no of ancestors" = j-1. i.e., if height increases by 1, no on nodes in the new level is at max double the number of nodes in the previous level.

    Only catch is while sorting the n sized array, you have to also sort their indices. If not you'll now there's a node with "no of ancestors" = 0, but you won't know which node it is.

    Complexity = O(N^2) for counting "no of ancestors" + O(NlogN) for sorting the N sized array.

    Hope I was clear.

  12. Srikant Aggarwal
    guest
    Posted 6 months ago #

    Assuming on space limitation, we can solve in O(n^2):

    Take another matrix n*n, child matrix, B.
    Parse through first matrix. If for any row i, A[i, j], A[i, k], ..., A[i, n] are non zero & for any j A[k,j], ..., A[n,j] are all zero then B[j, i] =1
    Similarly walk through the entire matrix A and fill B, keep account of the row where all elements are zero (This is the root).
    The complexity for this is O(n*n) = O(n^2).

    Now starting from root index, say a, get children (B[a, i] != 0) make children and and it to root. Now move through children, and continue the process till all rows are covered. Order is O(n).

    So resultant method order is O(n^2).

  13. Srikant Aggarwal
    guest
    Posted 6 months ago #

    We can optimize the above by noting that in order to find child, if A[j, k] != 0 we can remove k.
    Also after moving through every element if it is 1 we make it 0.

    For the given example :

    B is
    1 2 3 4
    1 0 0 0 0

    2 1 0 0 1

    3 0 1 0 0

    4 0 1 1 0


Reply

You must log in to post.

RSS feed for this topic