一、题目描述
给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?
示例:
输入: 3
输出: 5
解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树:
题目链接:https://leetcode-cn.com/problems/unique-binary-search-trees
思路
非常神奇的动态规划办法(我惊了反正)
首先想到这个题目要求的是二叉搜索树,然后可以根据根节点的选取来入手,列状态转移方程。
假设
d
p
(
n
)
dp(n)
dp(n)为整数n所能列出的二叉搜索树的数量
假设
f
(
i
)
f(i)
f(i)为第i个数为根节点时的二叉搜索树的数量
显然:
d
p
(
n
)
=
f
(
0
)
+
f
(
1
)
+
f
(
2
)
+
.
.
.
+
f
(
n
)
dp(n)=f(0)+f(1)+f(2)+...+f(n)
dp(n)=f(0)+f(1)+f(2)+...+f(n)
由于我们只需要考虑数量,故:
f
(
i
)
=
d
p
(
i
−
1
)
∗
d
p
(
n
−
1
)
f(i)=dp(i-1)*dp(n-1)
f(i)=dp(i−1)∗dp(n−1)
可以得出状态转移方程:
d
p
(
n
)
=
d
p
(
0
)
×
d
p
(
n
−
1
)
+
d
p
(
1
)
×
d
p
(
n
−
2
)
+
.
.
.
+
d
p
(
n
−
1
)
×
d
p
(
0
)
dp(n)=dp(0)\times dp(n-1)+ dp(1)\times dp(n-2)+...+dp(n-1)\times dp(0)
dp(n)=dp(0)×dp(n−1)+dp(1)×dp(n−2)+...+dp(n−1)×dp(0)
时间复杂度为O(n2),空间复杂度为O(n)
三、完整代码
class Solution {
public:
int numTrees(int n)
{
vector<int> dp;
dp.push_back(1);
for (int i=1;i<=n;i++)
{
int tmp=0;
for(int j=1;j<=i;j++)
{
tmp+=dp[j-1]*dp[i-j];
}
dp.push_back(tmp);
}
return dp[n];
}
};