简体   繁体   中英

How to identify the leaf nodes of a binary search tree

I recently came across the following problem that was said to have been asked in a technical interview:

Given the preorder traversal of a binary search tree, how do we identify the leaf nodes without building the tree?

Eg: [5,3,2,4,8,7,9]

The question was left vague by whoever posted it and given the vagueness, I'm not really sure what the approach should be for this one and I haven't been able to find verified solutions online.

How should this problem be solved?

Consider your example : [5,3,2,4,8,7,9]

Take the first element : 5 .

Since this is a preorder traversal that's root node for sure.

Now, in preorder traversal, after root u recur for left subtree and then right subtree .

And u also know that in BST :

 nodes in left subtree < root < nodes in right subtree 

Hence after 5, all the elements in series which are less than 5 belongs to left subtree . And similarly for right.

So u end up having this (you don't need to explicitly create tree) :

        5
     /    \
  [3,2,4] [8,7,9]

Now [3,2,4] is preorder traversal for left subtree part and [8,7,9] for right.

Recurse for both sub-arrays and the moment u are left with array of size 1, that's the leaf.

I assume we consider only perfect BSTs. Because if it is not perfect, there can be (possibly) multiple answers.

So looking at the examples and description of preorder traversal it is obvious that roots are taken first and then it 'does down' to leaves. As we have a perfect tree then we can see that leaves are always going in pairs. And also we need to 'skip' their parents.

Intuitively I would suggest going backwards, as 2 last elements are leaves ('*' denotes not leaves):

[*,*,2,4,*,7,9] <-- The overal procedure is as follows (going backwards):

  1. take 2 leaves;
  2. skip 1 node (their parent);
  3. repeat steps [1-2];
  4. skip 1 more node (parent of parents);
  5. done (there is no more elements left).

Now demo on a larger array (15 elements, again perfect tree):

[*,*,*,l,l,*,l,l,*,*,l,l,*,l,l] <-- where l denotes a leaf. Steps (also backwards):

  1. 1-4 from prevoius example;
  2. again 1-4 from previous example;
  3. skip 1 more node (parent of parents of parents);
  4. done (no more elements).

Hope, you got an idea.

As for programmatical approach, you can spot a repeating pattern in above intuitive approach and use a recursion depending on the height of the tree (can be easilly computed as log2(n+1) where n is number of elements in tree, also look wiki ) but probably starting from the beginning of the array. Pseudocode:

void getLeaves(int height) {
    if (height == 2) {       // there is only a parent and two childs (leaves)
        skip(1);             // skip 1 element
        take(2);             // next two are leaves, get them
    }
    else {
        skip(1);             // skip parent of parents (of parents ...)
        getLeaves(height-1); // call on left part of array
        getLeaves(height-1); // call on right part of array
    }
}
import java.util.ArrayList;

public class PreorderArrayToTree {

    static void printLeafNodes(ArrayList<Integer> list) {
        if(list.size()==0)return;
        if(list.size()==1) {
            System.out.print(list.get(0)+" ");
            return;
        }
        int parent = list.get(0);
        ArrayList<Integer> leftChild = new ArrayList<Integer>();
        ArrayList<Integer> rightChild =  new ArrayList<Integer>();
        for(int i=1; i<list.size(); i++) {
            if(list.get(i)<parent)leftChild.add(list.get(i));
            if(list.get(i)>parent)rightChild.add(list.get(i));
        };
        printLeafNodes(leftChild);
        printLeafNodes(rightChild);
    };

    public static void main(String[] args) {
        //int[] arr  = {10,5,1,7,40,50};
        //int[] arr =  {890, 325, 290, 530, 965};
        int[] arr = {3,2,4};
        ArrayList<Integer> list = new ArrayList<Integer>();
        for(int i=0; i<arr.length; i++)list.add(arr[i]);
        printLeafNodes(list);
    };
};
void printleafnode(int*arr, int size)
{
    int i = 0;

    while(i < size)
    {
        if(arr[i] > arr[i+1])
            i= i+1;
        else
        {
            if(arr[i] < arr[i+1])
            {
                printf(" %d " ,arr[i]);
                i= i+1;
            }
         }
    }
    printf(" %d ", arr[i]);
    printf("\n");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM