给定一个整数 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 种不同结构的二叉搜索树:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
一、思路
首先,我们知道1~n个数形成的二叉搜索树,其中序遍历是有序的,其结果为: [ 1 , . . . , n ] [1,...,n] [1,...,n]
假设根结点为
i
i
i,由二叉搜索树的性质可知:
[
1
,
.
.
.
i
−
1
]
[1,...i-1]
[1,...i−1]是它的左子树
[
i
+
1
,
.
.
.
n
]
[i+1,...n]
[i+1,...n]是它的右子树
且我们知道,它的左右子树也是一棵二叉搜索树
那么以 i i i为根结点的二叉搜索树的数量=左子树的数量乘以右子树的数量
所以可以递归地生成所有的BST,首先递归地生成所有的左右子树,然后设置双重循环,不断创建根节点,指向左右子树,再将根结点保存
C++代码:
class Solution {
public:
vector<TreeNode*> generateTrees(int n) {
if (n == 0)
return vector<TreeNode*>{};
return makeAllBST(1, n + 1);
}
// makeAllBST:生成所有的二叉搜索树
vector<TreeNode*> makeAllBST(int begin, int end) {
vector<TreeNode*> result;
if (begin >= end) {
result.push_back(NULL);
return result;
}
for (int i = begin; i < end; i++) {
vector<TreeNode*> left_trees = makeAllBST(begin, i);
vector<TreeNode*> right_trees = makeAllBST(i + 1, end);
for(auto left_tree : left_trees)
for (auto right_tree : right_trees) {
TreeNode* root = new TreeNode(i);
root->left = left_tree;
root->right = right_tree;
result.push_back(root);
}
}
return result;
}
};
执行效率: