题目:不同的二叉搜索树 II middle
给定一个整数 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
思路:
BST的性质,左子树小于根节点,右子树大于根节点。
以每个结点作为根节点,递归求出所有的BST
package leetCode.Recursion_Tacktrace;
import java.util.ArrayList;
import java.util.List;
public class lc_rt_95_generateTrees {
public List<TreeNode> generateTrees(int n) {
ArrayList<TreeNode> res = new ArrayList<>();
if (n == 0)
return res;
return helper(1, n);
}
//返回从start到end的所有BST
public List<TreeNode> helper(int start, int end) {
// 注意每次都要新建结果集合,不能将res传递进来
List<TreeNode> res = new ArrayList<>();
//此时没有数字,将 null 加入结果中
if (start > end) {
res.add(null);
return res;
}
//只有一个数字,当前数字作为一棵树加入结果中
if (start == end) {
res.add(new TreeNode(start));
return res;
}
//尝试每个数字作为根节点,创建BST
for (int i = start; i <= end; i++) {
//位置1
//递归得到所有可能的左子树集合
List<TreeNode> leftTreeList = helper(start, i - 1);
//递归得到所有可能的右子树集合
List<TreeNode> rightTreeList = helper(i + 1, end);
// //左子树右子树两两组合
for (TreeNode left : leftTreeList) {
for (TreeNode right : rightTreeList) {
//注意根节点要在这个位置新建,不能在位置1新建,否则后面相同的根节点,
// 其左右子结点会被改变。list存储的是对象的内存地址,后续操作会影响对象
TreeNode root = new TreeNode(i);
root.left = left;
root.right = right;
//加入到最终结果中
res.add(root);
}
}
}
return res;
}
}