题目:给定一个整数n,生成所有的包含1~n的结构唯一的二叉搜索树(BST);
例如,n = 3的话,则应该生成5个唯一的二叉树,表示如下:
1 3 3 2 1
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
思路:
- 对于二叉搜索树中的任意一个节点来说,其左子节点一定小于它,右子节点一定大于它!
- 既然是要生成所有结构唯一BST,那么一定会以1~n中的每个值生成一次根节点,然后将以当前节点为根节点而生成的所有左右子树链接起来;
- 对于每一个节点来说,它都是它左右子树的根节点,因此这道题可以递归来做;
- 以i为值生成根节点,用所有1 ~ i - 1的值生成其左子树,所有i + 1 ~ n的值生成其右子树(1 <= i <= n);
- 递归到1 ~ i - 1和i + 1 ~ n这两个区间去生成BST;
- 将左右子树都生成好的根节点放入到vector<TreeNode*>中;
鲁棒性:当n <= 0时,程序不能崩溃!
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<TreeNode*> generateTrees(int n)
{
vector<TreeNode*> res;
if(n <= 0) return res;
//使用递归的方法,分别以1到n中的每个数为值创建根节点,并生成所有的树
res = getTrees(1, n);
return res;
}
private:
vector<TreeNode*> getTrees(int start, int end)
{
vector<TreeNode*> res;
//递归基
if(start > end)
{
res.push_back(nullptr);
return res;
}
vector<TreeNode*> leftSubTree, rightSubTree;
for(int i = start; i <= end; ++i)
{
//将问题分解为两个子问题,分别去构建当前节点TreeNode(i)的左子树和右子树
leftSubTree = getTrees(start, i - 1);
rightSubTree = getTrees(i + 1, end);
//将当前节点的所有左右子树组合放入到res中
for(const auto < : leftSubTree)
{
for(const auto &rt : rightSubTree)
{
//构建当前节点
TreeNode *root = new TreeNode(i);
//链接左右子树
root->left = lt;
root->right = rt;
res.push_back(root);
}
}
}
return res;
}
};
运行结果如下: