题目描述:
给你一个整数 n ,请你生成并返回所有由 n 个节点组成且节点值从 1 到 n 互不相同的不同 二叉搜索树 。可以按 任意顺序 返回答案。
算法思想:
此题和力扣96题的思想一样,都可以运用穷举的方法快速解题,同样的,我们确定一个递归函数
public List<TreeNode> buildBST(int lo, int hi){};
递归函数buildBST实现构造区间[lo, hi]内所有符合定义的BST。
我们从根节点开始,穷举所有根节点的可能,并且递归的得到左右子树的BST列表。
for(int i = lo; i <= hi; i++) {
//构造出左右子树合法的BST
List<TreeNode> leftTree = buildBST(lo, i-1);
List<TreeNode> rightTree = buildBST(i + 1, hi);
}
根与左右子树的连接操作:由于一个区间同一个根节点能够形成多个不同的BST,所以这里我们需要挨个遍历左右子树的BST列表,构造出以i为根节点的所有BST。
for(int i = lo; i <= hi; i++) {
//构造出左右子树合法的BST
List<TreeNode> leftTree = buildBST(lo, i-1);
List<TreeNode> rightTree = buildBST(i + 1, hi);
//根节点穷举左右子树
for(TreeNode left:leftTree){
for(TreeNode right:rightTree){
TreeNode root = new TreeNode(i);
root.left = left;
root.right = right;
res.add(root);
}
}
}
完整代码实现:
public List<TreeNode> generateTrees(int n) {
if(n == 0){
return new LinkedList<>();
}
return buildBST(1, n);
}
//构造闭区间[lo, hi]组成的BST
public List<TreeNode> buildBST(int lo, int hi) {
List<TreeNode> res = new LinkedList<>();
if(lo > hi){
res.add(null);
return res;
}
//挨个作为根节点穷举
for(int i = lo; i <= hi; i++) {
//构造出左右子树合法的BST
List<TreeNode> leftTree = buildBST(lo, i-1);
List<TreeNode> rightTree = buildBST(i + 1, hi);
//根节点穷举左右子树
for(TreeNode left:leftTree){
for(TreeNode right:rightTree){
TreeNode root = new TreeNode(i);
root.left = left;
root.right = right;
res.add(root);
}
}
}
return res;
}