LeetCode 95. Unique Binary Search Trees II(二叉树)

题目来源:https://leetcode.com/problems/unique-binary-search-trees-ii/

问题描述

95. Unique Binary Search Trees II

Medium

Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1 ... n.

Example:

Input: 3

Output:

[

  [1,null,3,2],

  [3,2,null,1],

  [3,1,null,null,2],

扫描二维码关注公众号,回复: 5818602 查看本文章

  [2,1,3],

  [1,null,2,null,3]

]

Explanation:

The above output corresponds to the 5 unique BST's shown below:

 

   1         3     3      2      1

    \       /     /      / \      \

     3     2     1      1   3      2

    /     /       \                 \

   2     1         2                 3

------------------------------------------------------------

题意

给定整数n,求所有以1~n为节点值的二叉搜索树组成的数列(给定二叉搜索树的顺序为“左子树<根节点<右子树”)

------------------------------------------------------------

思路

引理:二叉搜索树的子树各节点的值是连续的。

引理的证明:反证法。假设存在一个子树的值不连续,不妨设该子树是根节点的左子树,则缺失的值必定小于左子树的最右节点的值,而该缺失的值在左子树的根节点或左子树的根节点的右子树中,即左子树的根节点或左子树的根节点的右子树中存在一个节点,其值小于左子树中的最右节点,这与二叉搜索树定义的“左子树<根节点<右子树”的搜索顺序矛盾。若该子树是根节点的右子树则同理可证。证毕。

根据引理,我们可以用递归的方式来构造。在1~n中遍历根节点的取值i,然后构造左子树1~(i-1),再构造右子树(i+1)~n.

具体实现上,要注意数组中的元素是持有的对象的引用,因此每个元素要new一个根节点出来,不能在原来的根节点上修改,否则会同步修改数组中的既有元素。

------------------------------------------------------------

代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    /**
    For debugging
    */
    private void printNode(TreeNode node)
    {
        if (node == null)
        {
            System.out.print("null");
            return;
        }
        System.out.print(node.val + ", ");
        printNode(node.left);
        printNode(node.right);
    }
    
    private List<TreeNode> recuGen(int begin, int end)
    {
        if (begin > end)
        {
            return new LinkedList<TreeNode>(){
                {
                    add(null);
                }
            };
        }
        if (begin == end)
        {
            return new LinkedList<TreeNode>(){
                {
                    add(new TreeNode(begin));
                }
            };
        }
        List<TreeNode> ret = new LinkedList<TreeNode>();
        for (int i = begin; i <= end; i++)
        {
            List<TreeNode> subL = recuGen(begin, i - 1);
            List<TreeNode> subR = recuGen(i + 1, end);
            for (TreeNode subl: subL)
            {
                for (TreeNode subr: subR)
                {
                    TreeNode root = new TreeNode(i);    // must new {@code root} in the inner iteration, because list only hosts the reference of the {@code root} object 
                    root.left = subl;
                    root.right = subr;
                    ret.add(root);
                }
            }
        }
        return ret;
    }
    
    public List<TreeNode> generateTrees(int n) {
        return n != 0 ? recuGen(1, n): Collections.emptyList();
    }
}

猜你喜欢

转载自blog.csdn.net/da_kao_la/article/details/89049190
今日推荐