一:题目
二:上码
class Solution {
public:
/**
思路:1.分析题意
二叉搜索树(左子树结点小于根节点 根节点小于右节点)
n=1时有一种形态,n=0的话,空树也是一种形态
当n=2的时候,二叉树有两种形状
当 n = 3的时候跟结点可以是1,2,3
根节点为1的时候,其右子树有两个结点,那么其有两种形态和n=2的形态相同
根节点为3的时候和根节点为1的情况类似
则dp[3] = 根节点为1的时候的形状数目+根节点为2的形状数+根节点为3的形状数目
2.动态规划5不步走
1>:确定dp数组的含义和下标的含义
dp[i]表示的是 n为i的时候的形状数
2>:确定dp数组的状态递推公式
dp[i] = dp[以j头结点的左子树结点个数] * dp[以j为头结点的右子树的结点个数]
因为要包含以头结点是[0,n],所以:
dp[i] += dp[j-1] * dp[i-j];
这里的j-1代表是比j小的个数有j-1个(左子树嘛就是结点的值比根节点小)
i-j代表的是比j大的有i-j个(同理)
3>:确定dp数组的如何初始化
dp[0] = 1,空树也是 一种形态
4>:确定dp数组的遍历顺序
从前向后遍历
5>:举例验证
*/
int numTrees(int n) {
vector<int>dp(n+1);
dp[0] = 1;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= i; j++) {//以j为头节点的话,
dp[i] += dp[j-1] * dp[i-j];//dp[j-1]:以j为头节点左子树结点个数;dp[i-j]:以j为头结点右子树的个数
}
}
return dp[n];
}
};
安!