问题:
给定一个特定的序列,最多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]
答案 0 :(得分:2)
假设给定的节点序列是我们将这些元素添加到BST中的顺序。
我们可以很容易地看到,如果两个节点a和b属于两个不同的分支,那么添加a和b的顺序将不影响最终结构。
在添加子项之前,我们只需要确保父项需要先添加。
对于示例[5,2,1,9,8]:应始终先添加5。
只有两种选择:添加2或添加9
所以,现在我们在从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))