所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。
一、题目
二、解法
思路分析:本题假设动态数组dp为互不相同的二叉搜索树的数量,有
d
p
[
0
]
=
1
,
d
p
[
1
]
=
1
,
d
p
[
2
]
=
2
dp[0]=1, dp[1]=1, dp[2]=2
dp[0]=1,dp[1]=1,dp[2]=2。二叉搜索树可以抽象成三部分:根节点,左子树和右子树。假设根节点取值为
i
i
i,除了根节点以外的节点数量为
i
−
1
i-1
i−1。那么左右子树根据数量的不同可以分成
j
−
1
j-1
j−1和
i
−
j
i-j
i−j,那么以
i
i
i为根节点的二叉搜索树的数量为
d
p
[
i
]
=
d
p
[
j
−
1
]
∗
d
p
[
i
−
j
]
dp[i]=dp[j-1]*dp[i-j]
dp[i]=dp[j−1]∗dp[i−j]。因为根节点的值从1到n,所以dp[i]采取累加的形式,
d
p
[
i
]
+
=
d
p
[
j
−
1
]
∗
d
p
[
i
−
j
]
dp[i]+=dp[j-1]*dp[i-j]
dp[i]+=dp[j−1]∗dp[i−j]。
程序如下:
class Solution {
public:
int numTrees(int n) {
vector<int> dp(n + 1); // dp[0] = 1, dp[1] = 1, dp[2] = 2, dp[3] = 5
dp[0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
dp[i] += dp[j - 1] * dp[i - j];
}
}
return dp[n];
}
};
复杂度分析:
- 时间复杂度: O ( n 2 ) O(n^2) O(n2)。
- 空间复杂度: O ( n ) O(n) O(n)。
三、完整代码
# include <iostream>
# include <vector>
using namespace std;
class Solution {
public:
int numTrees(int n) {
vector<int> dp(n + 1); // dp[0] = 1, dp[1] = 1, dp[2] = 2, dp[3] = 5
dp[0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
dp[i] += dp[j - 1] * dp[i - j];
}
}
return dp[n];
}
};
int main() {
Solution s1;
int n = 3;
int result = s1.numTrees(n);
cout << result << endl;
system("pause");
return 0;
}
end