不同的二叉搜索树 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
思路+代码+注释:
public List<TreeNode> generateTrees(int n) {
/*
思路:根节点可以是1~n的任意一个数
根节点是1时,左子树为空,右子树为2~n
根节点是2时,左子树为1,右子树为3~n
...
根节点是n时,左子树为1~n-1,右子树为空
生成一棵树,可以分解为生成根节点的左右子树这两个子问题,在将左右子树节点添加到根节点的左右子节点中
递归终止条件:节点范围小于0,此时所有节点确定完毕
*/
if (n==0)
{
return new ArrayList<TreeNode>();
}
return generateTree(1,n);
}
public List<TreeNode> generateTree(int start,int end)
{
List<TreeNode> treeNodeList=new ArrayList<>();
//当start>end时,所有节点确定完毕,往集合中添加null
if (start > end)
{
treeNodeList.add(null);
}else {
//根节点范围是start~end
for (int i = start; i <= end; i++) {
List<TreeNode> leftTree=generateTree(start,i-1);
List<TreeNode> rightTree=generateTree(i+1,end);
//将左右子树节点添加到根节点的左右子节点,并将根节点添加到集合中。每种不同的情况都是新的根节点
for (int j = 0; j < leftTree.size(); j++) {
for (int k = 0; k < rightTree.size(); k++) {
TreeNode root=new TreeNode(i);
root.left=leftTree.get(j);
root.right=rightTree.get(k);
treeNodeList.add(root);
}
}
}
}
return treeNodeList;
}