题目描述:
给定一个整数 n,生成所有由 1 … n 为节点所组成的 二叉搜索树 。
示例:
输入:3
输出:
[
[1,null,3,2],
[3,2,null,1],
[3,1,null,null,2],
[2,1,3],
[1,null,2,null,3]
]
解释:
以上的输出对应以下 5 种不同结构的二叉搜索树:
提示:
0 <= n <= 8
方法1:递归
主要思路:
(1)根据二叉搜索树的特性,其左边的结点小于根节点,右边的结点大于根节点,则对于 1到 n的数字,选择一个数字作为根节点, 则将原来的数组分割成了左右两个部分,而这两部分可以自己通过这个过程生成其自己的树的组成;
(2)当获得左右两部分的组成之后,就可以将左侧的组成作为根节点的左子树,右侧的组成作为根节点的右子树,生成该节点的所有树;
(3)然后换下一个结点重复上述递归步骤;
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<TreeNode*> helper(int begin,int end){
//范围内没有结点,返回空指针组成
if(begin>end)
return {nullptr};
vector<TreeNode*> all_trees;//存储当前范围内所有结点可以生成的树
//以该范围内各个结点作为根节点,来生成树的组合
for(int i=begin;i<=end;++i){
//当前结点的左侧部分结点生成的所有树的组合
vector<TreeNode*>left_trees= helper(begin,i-1);
//当前结点的右侧部分结点生成的所有树的组合
vector<TreeNode*>right_trees= helper(i+1,end);
//将左右两侧生成的树,作为当前结点的左右子树来生成当前结点的所有可能的树
for(TreeNode*& left_side:left_trees){
for(TreeNode*& right_side:right_trees){
TreeNode* cur_root=new TreeNode(i);
cur_root->left=left_side;
cur_root->right=right_side;
all_trees.emplace_back(cur_root);//将其中的一种树压入结果中
}
}
}
return all_trees;
}
vector<TreeNode*> generateTrees(int n) {
//处理特殊的情形
if(n==0)
return {};
//递归生成子树
return helper(1,n);
}
};