问题描述
思路
给定序列1 … n,为了构造序列的二进制搜索树(BST),我们可以遍历序列中的每个数字i,并使用数字i作为根,所以子序列1…(i-1)将放置在根的左侧分支上,同样右侧子序列(i+1)…n位于根的右侧分支上。然后我们可以递归地从子序列构造子树。通过上述方法,我们可以确保我们构建的BST都是独特的,因为它们具有独特的根。
G(n):长度为n的序列的BST数。
F(i, n), 1 <= i <= n:i是BST的根,序列范围从1到n的BST的数量。
长度为n的序列的BST数G(n)是F(i)使用每个数字i作为根的BST的总和即G(n) = F(1, n) + F(2, n) + … + F(n, n)
特别的
G(0)=1 空数
G(1)=1 长度为1(仅为根)
给定序列1 … n,我们从序列中选择一个数字i作为根,然后具有指定根的唯一BST F(i)的数量是其左右子树的BST数量的笛卡尔乘积。
例如,F(3,7):以数字3为根的唯一BST树的数量。从整个序列[1,2,3,4,5,6,7]构建一个独特的BST,以3为根,也就是说,我们需要从其左子序列构建一个唯一的BST [1] ,2]和右子序列中的另一个BST [ 4,5,6,7 ],然后将它们组合在一起(即笛卡尔积)。
可以发现序列[1,2] 长度为2,BST的数量为G(2),;序列[4,5,6,7]长度为4,BST的数量视为G(4),所以F(3,7) = G(2) * G(4)。
即F(i, n) = G(i-1) * G(n-i) 1 <= i <= n
所以G(n) = G(0) * G(n-1) + G(1) * G(n-2) + … + G(n-1) * G(0)
java实现
class Solution {
public int numTrees(int n) {
int [] G = new int[n+1];
G[0] = G[1] = 1;
for(int i=2; i<=n; ++i)
for(int j=1; j<=i; ++j)
G[i] += G[j-1] * G[i-j];
return G[n];
}
}