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未通过,n=2时报错。但本地測试全然正确):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
boolean[] b;
List<TreeNode> list;
Set<String> set = new HashSet<String>();
public List<TreeNode> generateTrees(int n) {
b = new boolean[n];
int[] a = new int[n];
list = new ArrayList<TreeNode>();
for(int i = 0; i < n; i++){
a[i] = i+1;
}
create(a,null,n);
return list;
}
/**
* 生成二叉搜索树
*/
private void create(int[] a,TreeNode root,int nn){
if(nn == 0){
TreeNode q = root;
String s = preOrder(q, "");
//System.out.println(s);
if(set.add(s)){
list.add(root);
}
return;
}
for(int i = 0; i < a.length; i++){
if(!b[i]){
b[i] = true;
TreeNode p = new TreeNode(a[i]);
root = insert(root,p);
create(a,root,nn-1);
root = delete(root,p);
b[i] = false;
}
}
}
/**
* 前序遍历
* @param root
* @param s
* @return
*/
private String preOrder(TreeNode root,String s){
if(root != null){
s += root.val;
if(root.left != null){
s = preOrder(root.left, s);
}
if(root.right != null){
s = preOrder(root.right, s);
}
}
return s;
}
/**
* 删除节点
* @param root
* @param p
* @return
*/
private TreeNode delete(TreeNode root, TreeNode p) {
if(root.val == p.val)
return null;
if(root.val < p.val){
root.right = delete(root.right,p);
}else{
root.left = delete(root.left,p);
}
return root;
}
/**
* 将新节点插入二叉搜索树
*/
private TreeNode insert(TreeNode root,TreeNode node){
TreeNode p = root;
if(p == null){
p = node;
return p;
}
if(node.val < p.val){
root.left = insert(p.left,node);
}else{
root.right = insert(p.right,node);
}
return root;
}
}
递归解法:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public List<TreeNode> generateTrees(int n){
List<TreeNode> list = new ArrayList<TreeNode>();
if(n <= 0){
list.add(null);
return list;
}
list = createTree(1,n);
return list;
}
/**
* 循环生产二叉搜索树
* @param i 開始值
* @param j 结束值
* @return
*/
private List<TreeNode> createTree(int i, int j){
List<TreeNode> list = new ArrayList<TreeNode>();
//起始大于结束值,加入null
if(i > j){
list.add(null);
return list;
}
//相等也即加入一个
if(i == j){
list.add(new TreeNode(i));
return list;
}
//循环加入
for(int k = i; k <= j; k++){
//左子树肯定比i小
List<TreeNode> left = createTree(i,k-1);
//右子树肯定比i大
List<TreeNode> right = createTree(k+1,j);
//将结果循环加入
for(TreeNode l:left){
for(TreeNode r:right){
TreeNode root = new TreeNode(k);
root.left = l;
root.right = r;
list.add(root);
}
}
}
return list;
}
}