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
=====================
Analysis:
It's not difficult to find out the recursive patten of this problem: 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.
However, I found difficulty about how to add the resulting trees into the final result set (ArrayList<TreeNode>). I tried several methods, referring to the solutions for previous problems I've done, but none of them worked.
After reviewing the solution form others, I found that we can create an ArrayList<TreeNode> in each recursive call, adding current node with all its possible sub-trees (tree node properties) then return them in the ArrayList<TreeNode>. Note that current node needed to be created for each possible sub-tree setting. And the resulting ArrayList<TreeNode> in recursive call, it stores only the current nodes, but not the nodes in its subtree. Take n=3 for example, if we choose 1 as in depth 0, when we are processing depth 1, the resulting ArrayList<TreeNode> would looks like {TreeNode(3), TreeNode(2)}, referring to the example provided in the problem.
/**
* 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 ArrayList<TreeNode> generateTrees(int n) {
return helper(1, n);
}
public ArrayList<TreeNode> helper(int left, int right){
ArrayList<TreeNode> rs = new ArrayList<TreeNode>();
if(left>right) rs.add(null);
else if(left==right) rs.add(new TreeNode(left));
else{
for(int i=left; i<=right; i++){
ArrayList<TreeNode> leftNodeSet = helper(left, i-1);
ArrayList<TreeNode> rightNodeSet = helper(i+1, right);
for(int j=0; j<leftNodeSet.size(); j++){
for(int k=0; k<rightNodeSet.size(); k++){
TreeNode curr = new TreeNode(i);
curr.left = leftNodeSet.get(j);
curr.right = rightNodeSet.get(k);
rs.add(curr);
}
}
}
}
return rs;
}
}