5.3.1独一无二的二叉搜索树
原创
©著作权归作者所有:来自51CTO博客作者喜欢打篮球的普通人的原创作品,请联系作者获取转载授权,否则将追究法律责任
文章目录
1.题目
- 题目要求
- 二叉搜索树定义:一句话就是左孩子比父节点小,右孩子比父节点大,还有一个特性就是”中序遍历“可以让结点有序。
- eg:
Input: 3
Output: 5
Explanation:
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 = 0 时赋为1,因为空树也算一种二叉搜索树;
那么 n = 1 时的情况可以看做是其左子树个数乘以右子树的个数,左右子树都是空树,所以1乘1还是1;
那么 n = 2 时,由于1和2都可以为根,分别算出来,再把它们加起来即可,n = 2 的情况可由下面式子算出
(这里的 dp[i] 表示当有i个数字能组成的 BST 的个数)
dp[2] = dp[0] * dp[1] (1为根的情况,则左子树一定不存在,右子树可以有一个数字)
+ dp[1] * dp[0] (2为根的情况,则左子树可以有一个数字,右子树一定不存在)
同理可写出 n = 3 的计算方法:
dp[3] = dp[0] * dp[2] (1为根的情况,则左子树一定不存在,右子树可以有两个数字)
+ dp[1] * dp[1] (2为根的情况,则左右子树都可以各有一个数字)
+ dp[2] * dp[0] (3为根的情况,则左子树可以有两个数字,右子树一定不存在)
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
2.代码
class Solution{
public:
int numTrees(int n)
{
vector<int> dp;
dp[0]=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];
}
};