Leetcode: Unique Binary Search Trees II

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
confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ.


OJ's Binary Tree Serialization:
The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.

Here's an example:
   1
  / 
 2   3
    /
   4
    
     5
The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}".

难度:98。没有做出来的一道题,很难,参考了其他人的想法,发现基本上只有一个版本,在纸上按照它的步骤推了几步终于看懂了。分析如下:

第一次遇到这种让你construct a BST的问题,而且结果并不是建立一个ArrayList<ArrayList<Integer>>型的,而是建立一个ArrayList<TreeNode>型的,这我就不知道怎么搞了,看了别人的才发现原来只要把几种方案的root放在最终的结果ArrayList<TreeNode>里面就好了,每个root有自己的left & right,但是不用放在这个ArrayList里面,只要指定好就可以了。Note that current node needed to be created for each possible sub-tree setting. 

以上是本问题的难点和不熟悉的地方,本题的思路参考了http://blog.csdn.net/linhuanmars/article/details/24761437

 choose one number i from n as root, pass all the numbers less than i to recursive call to construct the current root's left sub-tree, pass all the numbers greater than i to the recursive call to construct the current root's right sub-tree.  Take n=5 for example, when we choose root node = 3, then put 1,2 to recursive call to construct root node's left sub-tree, and put 4,5 to recursive call to contract root's right subtree.

这里helper(int left, int right)函数的作用是:用left到right这几个数来构造树的当前这一层,根节点i 依次从[left, right]里取值,左子树的构造通过递归helper(left, i-1)函数, 右子树的构造通过递归helper(i+1, right),然后返回值这样取:对于每一个(根节点,左子树,右子树)的组合模式,添加一次根节点进结果集。其实这样的结果集就是以[left, right]所有数字构成的所有BST的根的集合

 1 /**
 2  * Definition for binary tree
 3  * public class TreeNode {
 4  *     int val;
 5  *     TreeNode left;
 6  *     TreeNode right;
 7  *     TreeNode(int x) { val = x; left = null; right = null; }
 8  * }
 9  */
10 public class Solution {
11     public ArrayList<TreeNode> generateTrees(int n) {
12         if (n <= 0) return new ArrayList<TreeNode>();
13         return helper(1, n);
14     }
15     
16     public ArrayList<TreeNode> helper(int left, int right){
17         ArrayList<TreeNode> rs = new ArrayList<TreeNode>();
18         if(left>right) rs.add(null);
19         else{
20             for(int i=left; i<=right; i++){
21                 ArrayList<TreeNode> leftNodeSet = helper(left, i-1);
22                 ArrayList<TreeNode> rightNodeSet = helper(i+1, right);
23             
24                 for(int j=0; j<leftNodeSet.size(); j++){
25                     for(int k=0; k<rightNodeSet.size(); k++){
26                         TreeNode curr = new TreeNode(i);
27                         curr.left = leftNodeSet.get(j);
28                         curr.right = rightNodeSet.get(k);
29                         rs.add(curr);
30                     }
31                 }
32             }
33         }
34         return rs;
35     }
36 }
 1 public class Solution {
 2     public List<TreeNode> generateTrees(int n) {
 3         ArrayList<TreeNode> res = new ArrayList<TreeNode>();
 4         if (n < 0) {
 5             return res;
 6         }
 7         return helper(1, n);
 8     }
 9     
10     public ArrayList<TreeNode> helper(int l, int r) {
11         ArrayList<TreeNode> res = new ArrayList<TreeNode>();
12         if (l > r) {
13             res.add(null);
14         }
15         for (int i=l; i<=r; i++) {
16             ArrayList<TreeNode> leftset = helper(l, i-1);
17             ArrayList<TreeNode> rightset = helper(i+1, r);
18             for (int x=0; x<leftset.size(); x++) {
19                 for (int y=0; y<rightset.size(); y++) {
20                     TreeNode root = new TreeNode(i);
21                     root.left = leftset.get(x);
22                     root.right = rightset.get(y);
23                     res.add(root);
24                 }
25             }
26         }
27         return res;
28     }
29 }

 注意12-14行,不是return res, 这样res是[], 而是res.add(null); 这样res是[{}]。而且这样也保证了18行一定能进循环,否则leftset size为0,rightset size不为0的case进不了循环

原文地址:https://www.cnblogs.com/EdwardLiu/p/3960079.html