Given n, how many structurally unique BST's (binary search trees) that store values 1...n?
For example,
Given n = 3, there are a total of 5 unique BST's.
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
解题思路:
首先解释一下题目的意思,题目要求是给定数字序列1....n,求出可能的二叉搜索树的个数。
本题可以采用动态规划的方法来解决。具体公式[F(i, n) = G(i-1) * G(n-i)]。
给定一个序列1.....n, 来构造一个BST, 我们可以枚举系列中的每个数字i, 然后使用i作为根节点,很自然的,子序列1....(i-1)可以构成i的左子树,而(i+1)....n可以构成i的右子树,而且左子树和右子树叶都是BST.通过上面的方法,我们可以确保所构造的BST都是不同的,因为根节点是不同的。
为了求出不同的BST的个数,我们定义以下两个函数:
* G(N): 给定数字序列1....n, 求出可能的二叉树的个数。
* F(i, n) , i <= i <= n, 给定数字i, 并且数字i作为根节点,求出可能的二叉树个数。
根据以上两个定义的函数,可以得出G(n)就是题目的解,而G(n)可以通过求解F(i,n)得到,具体公式为:
G(n) = F(1, n) + F(2, n) + ... + F(n, n). '
G(0) = 1, G(1) = 1.
给定一个序列1.....n, 选择i作为BST的根节点,则二叉树的个数为:F(i,n)。 为了求F(i,n), 我们将F(i,n)拆分为左子树的个数和右子树的个数,因此可以得到以下公式:
F(i,n) = G(i-1) *(n-i) 1<= i <= n
具体代码如下:
class Solution {
public:
int numTrees(int n) {
if(n == 0) return 0;
if(n == 1) return 1;
vector ret(n+1,0);//增加第零个元素,所以size为n+1
ret[0] = 1;
ret[1] = 1;
for(int i = 2; i <= n; ++i)
{
for(int j = 1; j <= i; ++j)
ret[i] += ret[j-1] * ret[i-j];
}
return ret[n];
}
};
参考资料:https://discuss.leetcode.com/topic/8398/dp-solution-in-6-lines-with-explanation-f-i-n-g-i-1-g-n-i