生成二叉搜索树
LeetCode
给定一个整数 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
解决方案
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<TreeNode> generateTrees(int n) {
if(n == 0){
// 传入的是0,直接返回空的List
return new ArrayList<TreeNode>();
}
else{
//调用另一个多态的函数
return generateTrees(1,n);
}
}
public List<TreeNode> generateTrees(int start, int end){
List<TreeNode> allTrees = new ArrayList<>();
//递归出口
if(start > end){
//返回空的。注意这里不能直接返回size为0的List,
// 因为如果size为0的话,上一级的for遍历将会直接跳过,也返回size为0的list。导致最终的结果也是null。
allTrees.add(null);
return allTrees;
}
List<TreeNode> leftTrees = new ArrayList<>();
List<TreeNode> rightTrees = new ArrayList<>();
// i是根节点
for (int i = start; i<=end ; i++){
// 左侧的子树所有的可能情况
leftTrees = generateTrees(start, i-1);
// 右侧子树的所有可能情况
rightTrees = generateTrees(i+1, end);
// 左右侧所有可能情况进行组合
for(TreeNode left : leftTrees){
for(TreeNode right: rightTrees){
// 创建以i为根节点的二叉树
TreeNode root = new TreeNode(i, left,right);
// 该树结果保存
allTrees.add(root);
}
}
}
return allTrees;
}
}
注意:
-
递归出口返回尺寸不能是size= 0 。否则会导致上一层遍历结果直接跳过返回给上上级size = 0的list。导致最终结果为空。
-
思路和昨天的差不多。也是把大问题分成小问题,然后再回溯组合答案。
-
二叉搜索树左子树的任何一个数都小于根节点。右子树任何一个都大于根节点。