问题描述
给定一个整数 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
思路
这题的输入样例太特么的有迷惑性了。我特么看成二维数组了。
其实就是返回一个存储了TreeNode的ArrayList。
我们只把每个结点都当做根来处理(遍历可以做到这一点),然后递归的去建立二叉搜索树。(怎么做到这点?把所有的小于根结点的值用于递归的建立左子树,大于根结点的值用于递归的建立右子树即可)。甚至我们都不需要什么特殊的处理。为啥?因为题目给的是1-n,是有序的。所以只需要把i左边的数都当做左子树,右边的数都当做右子树即可。(方法一)
方法一
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
class Solution {
public List<TreeNode> generateTrees(int n) {
if(n < 1) return new ArrayList<>();
return generateTrees(1,n);
}
private ArrayList<TreeNode> generateTrees(int left, int right){
ArrayList<TreeNode> res = new ArrayList<>();
if(left > right){
res.add(null);
return res;
}
for(int i = left; i <= right; i++){
ArrayList<TreeNode> leftRes = generateTrees(left,i-1);
ArrayList<TreeNode> rightRes = generateTrees(i+1,right);
for(TreeNode l: leftRes){
for(TreeNode r: rightRes){
TreeNode curRoot = new TreeNode(i);
// 把左右子树接在根结点上
curRoot.left = l;
curRoot.right = r;
res.add(curRoot);
}
}
}
return res;
}
}