zoukankan      html  css  js  c++  java
  • 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;  
            }  
    这里需要加入一个空元素进去来表示这是一颗空树哈~ 并且同时也是保证下面循环时即使一边是空树,也会跑另一边~

      

      

  • 相关阅读:
    1002CSP-S模拟测试赛后总结
    「题解」:X国的军队
    1001CSP-S模拟测试赛后总结
    「题解」:联
    0929CSP-S模拟测试赛后总结
    「题解」:Kill
    「题解」:y
    Censoring【自动AC机】【水题毁我青春】【20190614】
    传说级快读
    针对值域与下标关系的总结
  • 原文地址:https://www.cnblogs.com/apanda009/p/7349103.html
Copyright © 2011-2022 走看看