LeetCode 96. Unique Binary Search Trees 解题报告
题目描述
Given n, how many structurally unique BST’s (binary search trees) that store values 1…n?
示例
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
限制条件
没有明确给出。
解题思路
我的思路:
这道题一看就知道肯定不可以真的去构建一棵棵不同的树然后去数它们的数目,所以需要做的就是找出n与树数目之间的关系。
列举前几项的结果如下:
n | BST的数目 |
---|---|
0 | 1 |
1 | 1 |
2 | 2 |
3 | 5 |
4 | 14 |
5 | 42 |
在我列举n=5的所有BST的过程中,我发现了这道题的规律:
以根节点k为界,分成左右两个子树,那么
以k为根节点的BST的数目=左子树可能的数目×右子树可能的数目
。 比如n=5,当根节点是2时,左子树只能是1,只有1种可能,而右子树包含3,4,5这3个元素,有5种可能,那么n=5并且以2为根节点的BST的数目 = 1
×
5 = 5,而n=5时所有的BST的数目等于各个元素为根节点时的数目之和,即nums[5] = nums[0] * [4] + nums[1] * nums[3] + nums[2] * nums[2] + nums[3] * nums[1] + nums[4] * nums[0] = 1 * 14 + 1 * 5 + 2 * 2 + 5 * 1 + 14 * 1 = 42。
因此根据这个思路,设置一个N+1大小的数组nums存储从0-n到对应的BST的个数,并且按照上面发现的公式去计算1-n对应的个数,最后返回nums[n]即可。
看了Discuss之后才知道原来我的解法就是动态规划的解法,仔细想想确实是符合动态规划的几个特征,上面给出的公式就是状态转移方程,边界是n=0的情况。而我这样的实现就是跟大神们最简洁的实现方式相同的,所以也不贴出他们的代码了,结合我上面的讲解,我的代码应该很容易理解。
代码
我的代码
class Solution {
public:
int numTrees(int n) {
vector<int> nums(n + 1, 0);
nums[0] = 1;
for (int i = 1; i <= n; i++)
for (int j = 0; j <= i - 1; j++)
nums[i] += nums[j] * nums[i - j - 1];
return nums[n];
}
};
总结
这道题不难,关键是要懂得利用根节点划分左右子树,通过它们的数目乘积得到以k为根节点的BST的数目,最后把所有这样的数目相加就能得到这样的结果,这个过程恰恰就是动态规划中子问题划分和求解的过程。
搞定了今天的坑,也写好了解题报告,明天再继续啦。坚持拼搏,努力加油~