• leetcode刷题笔记九十五题 不同的二叉搜索树II


    leetcode刷题笔记九十五题 不同的二叉搜索树II

    源地址: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 种不同结构的二叉搜索树:

    1 3 3 2 1
    / / /
    3 2 1 1 3 2
    / /
    2 1 2 3

    提示:

    0 <= n <= 8

    /**
    需要注意的是二叉搜索树性质,左侧小于根节点,右侧大于根节点
    本题可以使用递归法或动态规划法,这里动态规划使用复杂offSet
    主要是根据root位置, 调用左右子树位置的递归函数或DP数组结果
    */
    /**
     * Definition for a binary tree node.
     * class TreeNode(_value: Int = 0, _left: TreeNode = null, _right: TreeNode = null) {
     *   var value: Int = _value
     *   var left: TreeNode = _left
     *   var right: TreeNode = _right
     * }
     */
    import scala.collection.mutable
    object Solution {
        def generateTrees(n: Int): List[TreeNode] = {
            if(n == 0) return List()
            return helper(1, n)
    
            def helper(start: Int, end: Int): List[TreeNode]= {
                var res = mutable.ListBuffer[TreeNode]()
                
                //边界 补null
                if(start > end){
                    res += null
                    return res.toList
                }
    
                //只有一个结点, 插入
                if(start == end){
                    val root = new TreeNode(start)
                    res += root
                    return res.toList
                }
    
                //对左右子树调用递归函数,与root连接
                for(i <- start to end){
                    val leftTree = helper(start, i-1)
                    val rightTree = helper(i+1, end)
                    for(leftElem <- leftTree){
                        for(rightElem <- rightTree){
                            val root = new TreeNode(i)
                            root.left = leftElem
                            root.right = rightElem
                            res += root
                        }
                    }
                }
                return res.toList
            }
            if(n == 0) return List()
            return helper(1, n)
        }
        
    /**
    动态规划与递归思想基本一致
    初始状态 dp(0) = null
    动态转换方程 1 <= root <= n时  dp(root) = root + dp(root-1) + dp(root+1)
    需要注意的时dp(root+1)之前并没有得到计算,但是由树的构成特点可知,树的形状只与结点个数有关,相同长度的树的构成是一致,只需要对值进行修改即可
    故动态转换方程转变为 1 <= root <= n时 dp(root) = root + dp(root-1) + clone(dp(length-root), root)
    其中root-1为左子树节点数,length - root为右子树结点数, 此时根节点为root,由于右侧结点均大于root, 需对其全部加root 
    */
    /**
     * Definition for a binary tree node.
     * class TreeNode(_value: Int = 0, _left: TreeNode = null, _right: TreeNode = null) {
     *   var value: Int = _value
     *   var left: TreeNode = _left
     *   var right: TreeNode = _right
     * }
     */
    import scala.collection.mutable
    object Solution {
        def generateTrees(n: Int): List[TreeNode] = {
    
            def clone(n: TreeNode, offSet: Int): TreeNode = {
                if (n == null) return null
                val node = new TreeNode(n.value + offSet)
                node.left = clone(n.left, offSet)
                node.right = clone(n.right, offSet)
                return node
            }
    
            
            //注意初始化问题
            if(n == 0) return List()
            val dp: Array[mutable.ListBuffer[TreeNode]] = Array.fill(n+1)(mutable.ListBuffer())
            dp(0) = mutable.ListBuffer(null)
            for(length <- 1 to n ){
                for(rootPos <- 1 to length){
                    val left = rootPos - 1
                    val right = length - rootPos
                    for (leftElem <- dp(left); rightElem <- dp(right)){
                        val root = new TreeNode(rootPos)
                        root.left = leftElem
                        root.right = clone(rightElem, rootPos)
                        dp(length) +=  root 
                    }
                }
            }
            return dp(n).toList
        }
    }
    
  • 相关阅读:
    c 语言练习__去掉多余的空白字符_修正
    c 语言练习__求到N的阶乘的和。
    <<c 和指针 >> 部分笔记。
    AsciiDoc Markup Syntax Summary
    gdb 基本命令
    Ubuntu开启防火墙
    转载 jre精简
    windows 下指定jre运行java程序批处理指令
    虚拟机vmware的NAT网络
    liunx 端口权限
  • 原文地址:https://www.cnblogs.com/ganshuoos/p/13405881.html
Copyright © 2020-2023  润新知