95. Unique Binary Search Trees II

Given an integer 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

这道题是求解所有可行的二叉查找树,从Unique Binary Search Trees中我们已经知道,可行的二叉查找树的数量是相应的卡特兰数,不是一个多项式时间的数量级,所以我们要求解所有的树,自然是不能多项式时间内完成的了。算法上还是用求解NP问题的方法来求解,也就是N-Queens中介绍的在循环中调用递归函数求解子问题。思路是每次一次选取一个结点为根,然后递归求解左右子树的所有结果,最后根据左右子树的返回的所有子树,依次选取然后接上(每个左边的子树跟所有右边的子树匹配,而每个右边的子树也要跟所有的左边子树匹配,总共有左右子树数量的乘积种情况),构造好之后作为当前树的结果返回。同Different Ways to Add Parentheses

 代码如下: 

public ArrayList<TreeNode> generateTrees(int n) {  
    return helper(1,n);  
}  
private ArrayList<TreeNode> helper(int left, int right)  
{  
    ArrayList<TreeNode> res = new ArrayList<TreeNode>();  
    if(left>right)  
    {  
        res.add(null);  
        return res;  
    }  
    for(int i=left;i<=right;i++)  
    {  
        ArrayList<TreeNode> leftList = helper(left,i-1);  
        ArrayList<TreeNode> rightList = helper(i+1,right);  
        for(int j=0;j<leftList.size();j++)  
        {  
            for(int k=0;k<rightList.size();k++)  
            {  
                TreeNode root = new TreeNode(i);  
                root.left = leftList.get(j);  
                root.right = rightList.get(k);  
                res.add(root);  
            }  
        }  
    }  
    return res;  
}  

用map 加入记忆化搜索

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    HashMap<String, ArrayList<TreeNode>> map = new HashMap<>();
    public List<TreeNode> generateTrees(int n) {
       
       List<TreeNode> ans = new ArrayList<>();
         if (n < 1) {
            return ans;
        }
        
        ans = helper(1, n);
        return ans;
    }
    private ArrayList<TreeNode> helper(int left, int right)  {
        if (map.containsKey(left + "-" + right)){
            return map.get(left + "-" + right);
        }
        ArrayList<TreeNode> res = new ArrayList<TreeNode>();  
        if(left>right)  {  
            res.add(null);  
            return res;  
        }  
        for(int i=left;i<=right;i++)  {  
            ArrayList<TreeNode> leftList = helper(left,i-1);  
            ArrayList<TreeNode> rightList = helper(i+1,right);  
            for(int j=0;j<leftList.size();j++)  {  
                for(int k=0;k<rightList.size();k++)  {  
                    TreeNode root = new TreeNode(i);  
                    root.left = leftList.get(j);  
                    root.right = rightList.get(k);  
                    res.add(root);  
                }  
            }  
        }
        map.put(left + "-" + right, res);
        return res;  
    }  
}
if(left>right)  {  
            res.add(null);  
            return res;  
        }  
这里需要加入一个空元素进去来表示这是一颗空树哈~ 并且同时也是保证下面循环时即使一边是空树,也会跑另一边~

  

  

posted @ 2017-08-12 10:15  apanda009  阅读(158)  评论(0编辑  收藏  举报