题目描述
给你一个整数 n ,请你生成并返回所有由 n 个节点组成且节点值从 1 到 n 互不相同的不同 二叉搜索树 。可以按 任意顺序 返回答案。
思路:
二叉搜索树的特点是根节点大于左子树所有节点的值,小于右子树所有节点的值,且左右子树都满足该性质。
对于序列中任意一个值i,可以将区间分成两块,[1, i - 1],和[i + 1, n]。左子树和右子树的生成相较于原问题是序列长度缩小的子问题,因此可用递归法,且递归函数肯定包括区间的起点和终点。
递归函数:
vector<TreeNode*> generateTrees(start, end), 返回[start, end]区间内所有可行的二叉搜索树。
遍历顺序:
遍历[start, end]区间中的值i为当前根节点,递归调用[start, i - 1]和[i + 1, end]这两个区间,获得所有可行的左子树和右子树,最后从左子树集合选择一棵作为当前节点i的左子树,从右子树集合中选择一棵作为当前节点i的右子树,并且生成以当前节点i为根节点的树放入结果集合中即可。
终止条件:
递归的入口即为 generateTrees(1, n),出口为当 start>end 的时候,该区间没有数据,即当前二叉搜索树为空,返回空节点即可。
代码实现
/**
* 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*> generateTrees(int start, int end){
if(start > end){
return vector<TreeNode*>{nullptr};
}
vector<TreeNode*> allTrees; //每一层有一个数组,表示该层的所有可行二叉搜索树
//枚举所有可行根节点
for(int i = start; i <= end; i++){
vector<TreeNode*> leftTrees = generateTrees(start, i - 1); // 获得所有可行的左子树集合
vector<TreeNode*> rightTrees = generateTrees(i + 1, end); // 获得所有可行的右子树集合
//从左子树集合中选出一棵左子树,从右子树集合中选出一棵右子树,拼接到根节点上
for(auto &it1 : leftTrees)
for(auto &it2 :rightTrees){
TreeNode* root = new TreeNode(i);
root->left = it1;
root->right = it2;
allTrees.emplace_back(root);
}
}
return allTrees;
}
vector<TreeNode*> generateTrees(int n) {
if(!n){
return vector<TreeNode*>{};
}
return generateTrees(1, n);
}
};