-2

The problem:

Given a particular sequence of up to 50 integers, which represent nodes of a certain binary search tree (BST), how many permutations of this sequence are there, which will also give rise to exactly the same BST? Include the original sequence in your total count as 1 sequence.

For instance, answer = 6 for such a sequence [5,2,1,9,8]: [5,2,1,9,8] (itself, the original sequence given), [5,9,8,2,1], [5,2,9,1,8], [5,9,2,1,8], [5,2,9,8,1], [5,9,2,8,1]

evandrix
  • 6,041
  • 4
  • 27
  • 38
  • `give rise to exactly the same BST? ` can you explain more about this? does this mean the sequence printed when you traverse the tree? – Pham Trung Feb 03 '15 at 18:16
  • to maintain the tree insertion order in his example sequence, 2 must be inserted before 1, 9 before 8, and 5 before all of them. However the insertion order of 2 or 9 can be swapped since they are on opposite sides of the tree. Duplicate of: http://stackoverflow.com/questions/21211701/given-a-bst-and-its-root-print-all-sequences-of-nodes-which-give-rise-to-the-sa – Ben Grimm Feb 03 '15 at 18:35
  • @BenGrimm: yes, it's basically that duplicate qn; but I don't need to enumerate, I need to count and figure out how many there are. – evandrix Feb 04 '15 at 01:58
  • @PhamTrung: `give rise to exactly the same BST?` - well, as in my example, if I were to take the given sequence and build a BST from it, I want to count the total number of unique node sequences I can obtain by flattening that BST. – evandrix Feb 04 '15 at 02:00

2 Answers2

2

Assume that the given node sequence is the order in which we added those elements into the BST.

We can easily see that if two nodes a and b belong to two different branches, so the order of adding a and b will not affect the final structure.

We only need to ensure that the parent need to be added first, before its children is added.

For the example [5,2,1,9,8]: 5 should always added first.

There will be only two choices: add 2 or add 9

  • If we add 2: 1 can be added in any order
  • similarly, If we add 9: 8 can be added anytime after that

So, now we have our algo while travelling from root -> leaf:

int numberOfWays (Node node) {
    if(node is leaf) return 1;
    int a = numberOfWays(node.left);
    int b = numberOfWays(node.right);
    int x = number of node in the left;
    int y = number of node in the right;
    //nCr is combination, so we can choose x places in total of x + y positions
    return nCr(x+y,x) * a * b;
}
evandrix
  • 6,041
  • 4
  • 27
  • 38
Pham Trung
  • 11,204
  • 2
  • 24
  • 43
2

Suppose you have your example sequence [5,2,1,9,8]. The first node will become the root of the binary tree, so we know the first node must be 5.

From then on, all the nodes smaller than 5 will go to the left child, and all the nodes greater than 5 will go to the right child.

So you can solve this recursively, count the number of ways of making the left subtree (consisting of [2,1]) multiply by the number of ways of making the right subtree (consisting of [9,8]) and multiply by the number of ways of ordering the arrival of integers on opposite sides.

Sample code

def nCr(n,r):
   """Return number of ways of choosing r objects from n"""

   top, bottom = 1, 1
   for i in xrange(r):
      top *= n
      n = n - 1
      bottom *= r
      r = r- 1
   return top / bottom

def count_ways_to_make_bst(seq):
    if len(seq)<=1:
        return 1
    num_remaining = len(seq) - 1
    left = [r for r in seq[1:] if r>seq[0]]
    right = [r for r in seq[1:] if r<seq[0]]
    return count_ways_to_make_bst(left) * count_ways_to_make_bst(right) * nCr(num_remaining,len(left))
evandrix
  • 6,041
  • 4
  • 27
  • 38
Peter de Rivaz
  • 33,126
  • 4
  • 46
  • 75