首页 > 代码库 > Unique Binary Search Tree II | LeetCode

Unique Binary Search Tree II | LeetCode

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

For example,
Given n = 3, your program should return all 5 unique BST‘s shown below.

   1         3     3      2      1    \       /     /      / \           3     2     1      1   3      2    /     /       \                    2     1         2                 3
这一题跟I不一样的地方在于,这一题需要把所有的情况都输出出来,而第一题我们通过动态规划,可以将问题的结果很明白的表达出来(最后用卡塔兰数在O(n)的时间复杂度下就得到答案),而这一题的话如果我们使用动态规划的方法并不太好得到一个很直观的表达式,所以我们用递归的方法,依然按照I中的方法,选取k作为根,然后递归左右子树,分别得到左右子树的所有可能组合。
Java:
/** * Definition for binary tree * public class TreeNode { *     int val; *     TreeNode left; *     TreeNode right; *     TreeNode(int x) { val = x; left = null; right = null; } * } */public class Solution {   public List<TreeNode> generateTrees(int n)    {        return generateTrees(1,n);    }        public List<TreeNode> generateTrees(int start,int end)    {        List<TreeNode> result = new ArrayList<TreeNode>();        if (start > end)        {            result.add(null);            return result;        }        for (int i = start; i <= end; i++)        {            List<TreeNode> left =  generateTrees(start, i-1);            List<TreeNode> right = generateTrees(i+1, end);            for (int j = 0; j < left.size(); j++)            {                for (int k = 0; k < right.size(); k++)                {                    TreeNode root = new TreeNode(i);                    root.left = left.get(j);                    root.right = right.get(k);                    result.add(root);                }            }        }        return result;    }}

  这一题的代码我在这里解释一下,用最简单的例子,1、2、3序列来举例子来帮助自己理解。第一次调用的话,我必然是调用generateTrees(1,3),并不满足start>end的条件,进入for循环,接下来需要执行的是generateTrees(1,0),很明显的返回一个为空的List,我记作{null},所以generateTrees(1,3)的名为left的List为{null}(这个list.size()等于1而不是0),这里需要注意的是这个List是只属于generateTrees(1,3)的,如果把这个List跟别的List搞混淆的话,就比较难理解了。这么一来的话,继续执行right,即generateTrees(2,3),这个并不等于null,所以接下来需要执行进入属于generateTrees(2,3)的递归函数,当i等于2的时候,left={null},right=generateTrees(3,3)={3},这里的3我用特殊符号表示的原因是,这并不是一个值,而是一个二叉树的节点,节点的值为3,左右子树都是null,返回到上一层之后,新建的节点值为i,也就是2,左子树为null,右子树是刚刚得到的节点值为3的节点,这样一种右子树的情况就被保存下来;当i等于3的时候,left=generateTrees(2,2)={2},right=generateTrees(4,3)={null},因此这两个结果都被返回到generateTrees(2,3)中,因此属于generateTrees(1,3)的right={2,3},这里的2和3都是节点,再回到上一级,23被保存当根为1(generateTrees(1,3))时的right数组里面,因此最上层的result数组里面保存的是两个1,分别代表右子树为23的情况,也就是说,根为1的情况,就2种,然后最外层的循环继续执行,i=2、3...n,产生根为2时的二叉搜索树。最后的result是所有情况二叉搜索树的根节点的数组。

Unique Binary Search Tree II | LeetCode