计算产生相同BST的唯一节点序列的数量

时间:2015-02-03 18:12:42

标签: algorithm binary-search-tree

问题:

  

给定一个特定的序列,最多50个整数,代表   某个二叉搜索树(BST)的节点,有多少个排列   这个序列在那里,也会产生完全相同的序列   BST?将总计数中的原始序列包括为1个序列。

     

例如,对于这样的序列,回答= 6 [5,2,1,9,8]:[5,2,1,9,8]   (本身,给出的原始序列),[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]

2 个答案:

答案 0 :(得分:2)

假设给定的节点序列是我们将这些元素添加到BST中的顺序。

我们可以很容易地看到,如果两个节点a和b属于两个不同的分支,那么添加a和b的顺序将不影响最终结构。

在添加子项之前,我们只需要确保父项需要先添加

对于示例[5,2,1,9,8]:应始终先添加5。

只有两种选择:添加2或添加9

  • 如果我们添加2:1可以按任何顺序添加
  • 同样,如果我们添加9:8可以在此后的任何时间添加

所以,现在我们在从root旅行时有了算法 - >叶:

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;
}

答案 1 :(得分:2)

假设您有示例序列[5,2,1,9,8]。第一个节点将成为二叉树的根,因此我们知道第一个节点必须是5。

从那时起,小于5的所有节点都将转到左子节点,所有大于5的节点将转到右边的子节点。

所以你可以解决这个递归,计算使左子树(包括[2,1]乘以的方式的数量。制作正确的子树(由[9,8]组成)和乘以命令整数到达对方的方式的数量。

示例代码

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))