LeetCode 96. Unique Binary Search Trees
本博客转载自:http://www.cnblogs.com/grandyang/p/4299608.html
Solution1:
这道题实际上是Catalan Number卡塔兰数的一个例子。
1 n = 1
2 1 n = 2
/ \
1 2
1 3 3 2 1 n = 3
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
就跟斐波那契数列一样,我们把n = 0 时赋为1,因为空树也算一种二叉搜索树,那么n = 1时的情况可以看做是其左子树个数乘以右子树的个数,左右字数都是空树,所以1乘1还是1。那么n = 2时,由于1和2都可以为跟,分别算出来,再把它们加起来即可。n = 2的情况可由下面式子算出:
当数组为1,2,3,…,n时,基于以下原则构建的BST树具有【唯一性:以i为根结点的树,其左子树由[1, i-1]构成,其右子树由[i+1, n]构成】(参考自《leetcode-cpp 答案》)。
dp[2] = dp[0] * dp[1] (1为根的情况)
+ dp[1] * dp[0] (2为根的情况)
上面递归式的含义是:
2个元素组成的数的个数 = 左子树0个元素 * 右子树1个元素 (1为根的情况)
+ 左子树1个元素 * 右子树0个元素 (2为根的情况)
同理可写出 n = 3 的计算方法:
dp[3] = dp[0] * dp[2] (1为根的情况)
+ dp[1] * dp[1] (2为根的情况)
+ dp[2] * dp[0] (3为根的情况)
上面递归式的含义是:
3个元素组成的数的个数 = 左子树0个元素 * 右子树2个元素 (1为根的情况)
+ 左子树1个元素 * 右子树1个元素 (2为根的情况)
+ 左子树2个元素 * 右子树0个元素 (3为根的情况)
由此可以得出卡塔兰数列的递推式为:
时间复杂度
O(n2)
O
(
n
2
)
,空间复杂度
O(n)
O
(
n
)
class Solution {
public:
int numTrees(int n) {
vector<int> dp(n + 1, 0);
dp[0] = 1;
dp[1] = 1;
for (int i = 2; i <= n; ++i) {
for (int j = 0; j < i; ++j) {
dp[i] += dp[j] * dp[i - j - 1];
}
}
return dp[n];
}
};