Loading

Leetcode95. 不同的二叉搜索树 II

95. 不同的二叉搜索树 II

Difficulty: 中等

给定一个整数 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

提示:

  • 0 <= n <= 8

Solution

思路:回溯法。因为二叉树搜索树的特性,每次选择一个数做根结点,然后获取左子树的所有组合和右子树的所有组合方式,对它们进行组合就能得到当前树的所有组合方式。

Language: java

​/**
 * 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) {
        return helper(1, n);
    }

    private List<TreeNode> helper(int s, int e){  //s表示开始的编号,e表示结束的编号
        if(s == e) {  //当只有一个编号时,不需要组合,只返回含一个结点的list
            TreeNode t = new TreeNode(s);
            return new ArrayList<>(){{add(t);}};
        }
        List<TreeNode> treeList = new ArrayList<>();
        for(int i = s+1; i < e; i++){
            List<TreeNode> left = helper(s, i-1);  // 获取右子树的所有组合方式
            List<TreeNode> right = helper(i+1, e);// 获取左子树的所有组合方式
            for(TreeNode leftTree : left){
                for(TreeNode rightTree : right){
                    TreeNode node = new TreeNode(i);
                    node.left = leftTree;
                    node.right = rightTree;
                    treeList.add(node);
                }
            }
        }
        List<TreeNode> left = helper(s, e-1);  
        for(TreeNode tree : left){  //  以e为根结点的组合方式
            TreeNode node = new TreeNode(e);
            node.left = tree;
            node.right = null;
            treeList.add(node);
        }
        List<TreeNode> right = helper(s+1, e);
        for(TreeNode tree : right){  //  以s为根结点的组合方式
            TreeNode node = new TreeNode(s);
            node.right = tree;
            node.left = null;
            treeList.add(node);
        }
        return treeList;
    }
}

注意:在遍历过程中,一个结点都有明确的左孩子和右孩子,然而该结点可能是其他结点的孩子,但最终不影响树的表示结果,图如下:
图片1

posted @ 2021-02-24 16:20  yoyuLiu  阅读(48)  评论(0编辑  收藏  举报