题目相关
题目链接
LeetCode中国,https://leetcode-cn.com/problems/unique-binary-search-trees-ii/。注意需要登录。
题目描述
给定一个整数 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
题目分析
题意分析
根据输入 n,构造所有二叉搜索树。这里涉及到数据结构的一个名词二叉搜索树(BST,Binary Search Tree)。
二叉搜索树
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉树。
以上定义来自百度百科。
样例数据分析
略。请参考数据结构书籍。
算法思路
根据 BST 的定义,我们知道构造 BST 一般使用递归方法。假设我们要构造 [l, r] 这个区间的 BST。我们以数据 为跟节点,递归构造 [l, i-1] 这个这个左区间的 BST,递归构造 [i+1, r] 这个右区间的 BST。然后使用乘法的原理,先遍历 [l, i-1] 这个左区间的 BST,再遍历 [i+1, r] 这个右区间的 BST,加上跟节点 i,合并构造成为一个 BST。
读上去有点拗口。我们来看最终的代码。
搜索终止条件
我们是搜索区间 [l, r],自然终止的条件就是 l>r。
搜索函数参数
本题和其他 DFS 有一点不一样。建议提供两个参数:
1、参数1:l,表示区间的左边界。
2、参数2:r,表示区间的右边界。
因此 DFS 函数原型可以定义如下:
vector<TreeNode*> dfs(int l, int r);
开始调用方式
直接从 [1, n] 这个区间调用即可。
回溯
不需要。
AC 参考代码
/**
* 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) {
if (0==n) {
//特例处理
return vector<TreeNode*>();
}
return dfs(1, n);
}
/*
参数1:l表示要构造的左边界
参数2:r表示要构造的右边界
*/
vector<TreeNode*> dfs(int l, int r) {
vector<TreeNode*> ans;//返回值
//结束条件
if (l>r) {
ans.push_back(NULL);
return ans;
}
for (int i=l; i<=r; i++) {
//以 i 为跟节点
//遍历左区间
auto left = dfs(l, i-1);
//遍历右区间
auto right = dfs(i+1, r);
//遍历左右子树构造完整树
for (auto < : left) {
for (auto &rt : right) {
//构造跟节点
auto root = new TreeNode(i);
//加入左子树
root->left = lt;
//加入右子树
root->right = rt;
//将该树加入答案中
ans.push_back(root);
}
}
}
return ans;
}
};

吐槽一下,竟然算法效率这么低。不过也是,这么多递归,算法效率好不到哪里去。
代码讲解
1、就是 n=0 的时候,会出现一个特例,如果没有处理的话,输出是不对的。
2、空子树要求输出 NULL,所以在结束的时候要加上 NULL。
LeetCode 二叉搜索树生成

本文介绍如何解决LeetCode上的题目“不同的二叉搜索树 II”。通过递归方法,详细解析了如何生成所有可能的二叉搜索树,并附带了C++代码实现。
753

被折叠的 条评论
为什么被折叠?



