zoukankan      html  css  js  c++  java
  • leetcode 95 不同的二叉搜索树II

    package com.example.lettcode.dailyexercises;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.LinkedList;
    import java.util.List;
    
    /**
     * @Class GenerateTrees
     * @Description 95 不同的二叉搜索树II
     * 给定一个整数 n,生成所有由 1 ... n 为节点所组成的 二叉搜索树 。
     * 示例:
     * 输入:3
     * 输出:
     * [
     *   [1,null,3,2],
     *   [3,2,null,1],
     *   [3,1,null,null,2],
     *   [2,1,3],
     *   [1,null,2,null,3]
     * ]
     * 解释:
     * 以上的输出对应以下 5 种不同结构的二叉搜索树:
     * <p>
     * 1         3     3      2      1
     *        /     /      /       
     * 3     2     1      1   3      2
     * /     /                        
     * 2     1         2                 3
     * <p>
     * 提示:
     * 0 <= n <= 8
     * @Author 
     * @Date 2020/7/15
     **/
    public class GenerateTrees {
        static class TreeNode {
            int val;
            TreeNode left;
            TreeNode right;
    
            TreeNode() {
            }
    
            TreeNode(int val) {
                this.val = val;
            }
    
            TreeNode(int val, TreeNode left, TreeNode right) {
                this.val = val;
                this.left = left;
                this.right = right;
            }
        }
    
    
        public static List<TreeNode> generateTrees(int n) {
            if (n < 1) return new ArrayList<>();
            // dp[i] 表示n=i时所能取得的二叉搜索树
            List<TreeNode>[] dp = new List[n + 1];
            for (int i = 0; i <= n; i++) {
                dp[i] = new ArrayList<>();
            }
            dp[1] = new ArrayList<>(Arrays.asList(new TreeNode(1)));
            for (int i = 2; i <= n; i++) {
                for (int j = 0; j < i; j++) {
                    dp[i].addAll(getNodeList(dp, j, i - j - 1));
                }
            }
            return dp[n];
        }
    
        private static List<TreeNode> getNodeList(List<TreeNode>[] dp, int i, int j) {
            List<TreeNode> res = new ArrayList<>();
            // 左子树不变,右子树加上root.val
            int sizeL = i == 0 ? 1 : dp[i].size(); // 左子树个数
            int sizeR = j == 0 ? 1 : dp[j].size(); // 右子树个数
            int size = sizeL * sizeR; // 左右子树的可能性
            for (int k = 0; k < size; k++) {
                TreeNode root = new TreeNode(i + 1);
                // k/sizeR 表示每次以此选择左子树,然后依次把右子树都遍历一遍
                root.left = i == 0 ? null : dp[i].get(k / sizeR);
                // (k%sizeR) 从0...sizeR-1 + roo.val ,是因为右子树的元素都比根节点大,分别大1,2,3...,sizeR-1
                root.right = j == 0 ? null : copyTree(dp[j].get(k % sizeR), root.val);
                res.add(root);
            }
            return res;
        }
    
        // 递归是为了右子树的每个元素都加上sizeAdd(也就是根节点的值)
        private static TreeNode copyTree(TreeNode treeNode, int sizeAdd) {
            if (treeNode == null) return null;
            TreeNode node = new TreeNode(treeNode.val + sizeAdd);
            node.left = copyTree(treeNode.left, sizeAdd);
            node.right = copyTree(treeNode.right, sizeAdd);
            return node;
        }
    
        public static void main(String[] args) {
            int n = 5;
            List<TreeNode> treeNodeList = generateTrees(n);
            System.out.println("GenerateTrees demo01 result:" + treeNodeList.size());
        }
    }
    
  • 相关阅读:
    各大代码托管服务器的分析比较
    《构建之法》读后
    【转】简单的程序诠释C++ STL算法系列之十五:swap
    【转】error while loading shared libraries: xxx.so.x" 错误的原因和解决办法
    C++大会感悟
    一次DDOS攻击引起的安全漫谈
    为npm设置代理,解决网络问题
    Rust 中的类型转换
    Rust 智能指针(二)
    软件设计原则
  • 原文地址:https://www.cnblogs.com/fyusac/p/13355583.html
Copyright © 2011-2022 走看看