简单题目(只需要返回多少种):
给你一个整数 n
,求恰由 n
个节点组成且节点值从 1
到 n
互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
示例:
输入:n = 3
输出:5
解题思路:
二叉搜索树关键的性质是根节点的值大于左子树所有节点的值,小于右子树所有节点的值,且左子树和右子树也同样为二叉搜索树。
本题我们使用动态规划算法来实现,把n个节点的问题,可以看作是更多个小的子问题来解
1.我们用G(n)来表示n个节点一共能组成多少个不同的二叉搜索树
2.fn[i]表示以i为根节点的二叉搜索树的个数
3.当i为根节点时,左子树的节点个数为i-1个,右子树的节点个数为n-i
4.那么fn[i]=G(i-1)*G(n-i)
源代码如下:
class Solution {
public://int numTrees(int n) {vector<int> fn(n+1,0);fn[0]=1;//没有节点,只有一种fn[1]=1;//只有一个节点,只能构成一种二叉搜索树for(int i=2;i<=n;i++){for(int j=1;j<=i;j++){//为了节省代码,我们直接用fn[i]代替G(i)fn[i]+=(fn[j-1]*fn[i-j]);}}return fn[n];}
};
升级题目:(需返回所有的二叉搜索树)
给你一个整数 n
,请你生成并返回所有由 n
个节点组成且节点值从 1
到 n
互不相同的不同 二叉搜索树 。可以按 任意顺序 返回答案。
输入:n = 3
输出:[[1,null,2,null,3],[1,null,3,2],[2,1,3],[3,1,null,null,2],[3,2,null,1]]
解题思路:
使用递归算法来实现本题
1.在(start,i-1)中递归地选择左子树的根节点,在(i+1,end)中递归地选择右子树的根节点
2.以当前i为根节点,选择合适的左子树和右子树,组合成一个符合条件的二叉搜索树
3.将当前这个二叉搜索树放进结果数组中即可
源代码如下:
class Solution {
public:vector<TreeNode*> generateTrees(int n) {if(n==0) return {};//没有节点 直接返回空数组//起始从(1,n)中选择return dfs(1,n);}
private:vector<TreeNode*> dfs(int start,int end){//当start>end时,返回空if(start>end) return {nullptr};vector<TreeNode*> resTree;//结果数组for(int i=start;i<=end;i++){//构成左子树vector<TreeNode*> leftTree=dfs(start,i-1);//构成右子树vector<TreeNode*> rightTree=dfs(i+1,end);//组合二叉搜索树for(auto& left:leftTree){for(auto& right: rightTree){//创建一个根节点为i的二叉树tempTreeTreeNode* tempTree=new TreeNode(i);tempTree->left=left;tempTree->right=right;//将临时结果放入结果数组中resTree.push_back(tempTree);}}}//返回结果return resTree;}
};