zoukankan      html  css  js  c++  java
  • leetcode 95 Unique Binary Search Trees II ----- java

    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

    是第96题的延伸,要求出所有可能性。

    刚开始写了一个回溯法,但是由于没有办法在TreeNode中重写equals,导致需要重写的东西很多(主要这样做的话,一个一个添加TreeNode。会出现重复的情况),也就导致了时间很长。一百多ms。

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        List list = new ArrayList<TreeNode>();
        public List<TreeNode> generateTrees(int n) {
            
            if( n == 0)
                return list;
            int[] pos = new int[n];
            for( int i = 0;i<n;i++){
                pos[i] = 1;
                TreeNode root = new TreeNode(i+1);
                getResult(root,pos);
                pos[i] = 0;
            }
            return list;
        }
    
        public void getResult(TreeNode root,int[] pos){
    
            int flag = 0;
            for( int i = 0;i<pos.length;i++){
                if( pos[i] == 0){
                    addNode(root,i);
                    pos[i] = 1;
                    getResult(root,pos);
                    delNote(root,i);
                    pos[i] = 0;
                    flag = 1;
                }
            }
            if( flag == 0){
                TreeNode ans = getAns(root);
                if( !isExist(ans) )
                    list.add(ans);
            }
                
    
        }
        public boolean isExist(TreeNode ans){
            int size = list.size();
            for( int i = 0;i<size;i++){
                if( isSame((TreeNode)list.get(i),ans) )
                    return true;
            }
            return false;
                  
        }
        public boolean isSame(TreeNode node1,TreeNode node2){
            if( node1.val != node2.val)
                return false;
            if( node1.left != null && node2.left != null){
                if( !isSame(node1.left,node2.left) )
                    return false;
            }else if( node1.left == null && node2.left == null)
                ;
            else 
                return false;
            if( node1.right != null && node2.right != null){
                if( !isSame(node1.right,node2.right) )
                    return false;
            }else if( node1.right == null && node2.right == null )
                ;
            else 
                return false;
            return true;
        }
        
        public TreeNode getAns(TreeNode root){
            
            TreeNode ans = new TreeNode(root.val);
            if( root.left != null )
                ans.left = getAns(root.left);
            if( root.right != null)
                ans.right = getAns(root.right);
            return ans;        
        }
        
        
        
        public void addNode(TreeNode root,int i ){
            while( true){
                if( i+1 > root.val ){
                    if( root.right == null){
                        root.right = new TreeNode(i+1);
                        return ;
                    }else
                        root = root.right;
                }else{
                    if( root.left == null){
                        root.left = new TreeNode(i+1);
                        return ;
                    }else
                        root = root.left;
                }
            }
        }
        public void delNote(TreeNode root,int i){
            while( true){
                if( i+1 > root.val ){
                    if( i+1 == root.right.val ){
                        root.right = null;
                        return ;
                    }else
                        root = root.right;
                }else{
                    if( i+1 == root.left.val ){
                        root.left = null;
                        return ;
                    }else
                        root = root.left;
                }
            }
        }
        
    }

    然后看了网上的解答,有两个我认为还不错,一个是根据树的结构来回溯,效率很高,不会出现重复,

    /**
     * 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) {
            
            if(n == 0) {
                return new ArrayList<TreeNode>();
            }
            
            return gen(1, n);
        }
        
        List<TreeNode> gen(int start, int end) {
            ArrayList<TreeNode> heads = new ArrayList<TreeNode>();
            if(start > end) {
                heads.add(null);
                return heads;
            }
            
            for(int i = start; i <= end; i++) {
                
                List<TreeNode> lefts = gen(start, i - 1);
                List<TreeNode> rights = gen(i + 1, end);
                
                for(TreeNode left : lefts) {
                    for(TreeNode right : rights) {
                        TreeNode head = new TreeNode(i);
                        head.left = left;
                        head.right = right;
                        heads.add(head);
                    }
                }
            }
            
            return heads;
            
        }
    }

     还有一种动态规划其实也就是第二种方法的改良。

    public static List<TreeNode> generateTrees(int n) {
        List<TreeNode>[] result = new List[n + 1];
        result[0] = new ArrayList<TreeNode>();
        if (n == 0) {
            return result[0];
        }
    
        result[0].add(null);
        for (int len = 1; len <= n; len++) {
            result[len] = new ArrayList<TreeNode>();
            for (int j = 0; j < len; j++) {
                for (TreeNode nodeL : result[j]) {
                    for (TreeNode nodeR : result[len - j - 1]) {
                        TreeNode node = new TreeNode(j + 1);
                        node.left = nodeL;
                        node.right = clone(nodeR, j + 1);
                        result[len].add(node);
                    }
                }
            }
        }
        return result[n];
    }
    
    private static TreeNode clone(TreeNode n, int offset) {
        if (n == null) {
            return null;
        }
        TreeNode node = new TreeNode(n.val + offset);
        node.left = clone(n.left, offset);
        node.right = clone(n.right, offset);
        return node;
    }
  • 相关阅读:
    键盘ASCII码
    Pandas常用功能总结
    TensorFlow之多核GPU的并行运算
    Linux中目录以及路径问题
    菜鸟的服务器进阶
    ORA-02447: cannot defer a constraint that is not deferrable
    ORA-25153: Temporary Tablespace is Empty解决方法
    查询当前会话进程号
    Oracle中的USEREVN()
    Oracle物理结构与逻辑结构
  • 原文地址:https://www.cnblogs.com/xiaoba1203/p/5984917.html
Copyright © 2011-2022 走看看