思路
本问题属于动态规划问题。
用
f
(
n
)
f(n)
f(n)表示
n
n
n个数字时,可以组成二叉搜索树的目数。
任取
i
i
i满足
0
<
i
≤
n
0{\lt}i{\le}n
0<i≤n作为根节点,则其左子树有
i
−
1
i-1
i−1个节点,有子树有
n
−
i
n-i
n−i个节点。即分别有
f
(
i
−
1
)
f(i-1)
f(i−1),
f
(
n
−
i
)
f(n-i)
f(n−i)种组合。
那么
i
i
i作为根节点的二叉搜索树的组合共有
f
(
i
−
1
)
⋅
f
(
n
−
i
)
f(i-1){\cdot}f(n-i)
f(i−1)⋅f(n−i)种。
这样,我们就得出了递推方程:
f
(
n
)
=
∑
i
=
1
n
f
(
i
−
1
)
⋅
f
(
n
−
i
)
f(n) = \sum_{i=1}^nf(i-1){\cdot}f(n-i)
f(n)=i=1∑nf(i−1)⋅f(n−i)
代码
class Solution {
public:
int numTrees(int n) {
if (n == 0)
return 1;
vector<int> dp(n + 1, 0);
//初始条件:
dp[0] = 1;
dp[1] = 1;
//递推过程,i对应公式中的n,j对应公式中的i
for (int i = 2; i < n + 1; i++) {
for (int j = 1; j <= i; j++) {
dp[i] += dp[i - j] * dp[j - 1];
}
}
return dp[n];
}
};