LeetCode 96. 不同的二叉搜索树

简介: LeetCode 96. 不同的二叉搜索树

 LeetCode 96. 不同的二叉搜索树

   

给你一个整数 n ,求恰由 n 个节点组成且节点值从 1n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。

示例 1:

image.gif 编辑
输入:n = 3
输出:5

示例 2:

输入:n = 1
输出:1

提示:

    • 1 <= n <= 19


    思路

    参考:LeetCode题解,包含图解。

      1. 二叉搜索树:根的左孩子的值 < 根节点值,根的右孩子的值 > 根节点值
      2. 只需取其中任意一个数i作为根,取这个数左边的数[0,i-1]构建左子树,取这个数右边的数[i+1,n]构建右子树即可
      3. 此时左子树本身可能有m种构建方式,右子树有n种构建方式,所以取i作为根的二叉搜索树的种类为m*n
      4. 对于整个序列1~n都可能作为根节点,根有n种可能。所以整个序列构建二叉搜索树,所有种类等于分别取1~n为根的二叉搜索树种类和
      5. 注意 特殊边界dp[0]为0个数构成的二叉搜索树种类为1,因为null可以认为是一颗 空二叉搜索树


      举例

      在排除根节点本身所占的一个节点数后,前面一项是左子树情况数,后面一项是右子树情况数,相加即可。比如这里求解n=3的情况:

      节点数组为[1,2,3],dp[3] = dp[0]*dp[2] + dp[1]*dp[1] + dp[2]*dp[0],可以理解成:

        • 根节点为 1 时:因为没有比1小的节点,所以左子树可能的情况数为0;又因为 2,3 > 1,所以右子树可能情况数为2dp[0]*dp[2] = 1*2=2
        • 根节点为 2 时:因为 1 < 2 ,所以左子树可能的情况数为1;又因为 3 > 2,所以右子树可能情况数也为1dp[1]*dp[1] = 1*1=1
        • 根节点为 3 时:因为1,2 < 3,所以左子树可能的情况数为2;又因为没有比3大的节点,右子树可能情况数为0dp[2]*dp[0] = 2*1=2
        • 所以一共的可能数:2 + 1 + 2= 5,其中dp[2]可以分别表示为以 1或2 为根节点的二叉搜索树,所以 dp[2] = 2,dp[0] = 1 表示为空二叉搜索树,dp[1] = 1表示仅有一个节点的二叉搜索树。


        时间复杂度

        空间复杂度

        /* 思路 参考:https://leetcode.cn/problems/unique-binary-search-trees/solutions/1319816/a-qiu-javadi-gui-jie-fa-by-emeraki-qi2d/https://leetcode.cn/problems/unique-binary-search-trees/solutions/6693/hua-jie-suan-fa-96-bu-tong-de-er-cha-sou-suo-shu-b/1. 二叉搜索树:根的左孩子的值 < 根节点值,根的右孩子的值 > 根节点值2. 只需取其中任意一个数i作为根,取这个数左边的数[0,i-1]构建左子树,取这个数右边的数[i+1,n]构建右子树即可3. 此时左子树本身可能有m种构建方式,右子树有n种构建方式,所以取i作为根的二叉搜索树的种类为m*n4. 对于整个序列1~n都可能作为根节点,根有n种可能。所以整个序列构建二叉搜索树,所有种类等于分别取1~n为根的二叉搜索树种类和*/funcnumTrees(nint) int {
        dp :=make([]int, n+1)
        // 特殊边界:dp[0]为0个数构成的二叉搜索树种类为1,因为null可以认为是一颗空二叉搜索树dp[0], dp[1] =1, 1// i表示当前想要表示的节点总数,从前往后依次递推fori :=2; i<=n; i++ {
        // j:表示当前一共有i个节点时,左子树的节点个数// 根节点本身也占1个节点数,排除根节点后,所以 j <= i-1 → j < iforj :=0; j<i; j++ {
        // 前一项dp[j]是左子树种数,后一项dp[i-j-1]是右子树种数,根节点也占一个数量// 举例:dp[3] = dp[0]*dp[2] + dp[1]*dp[1] + dp[2]*dp[0]dp[i] += (dp[j]*dp[i-j-1])
                }
            }
        returndp[n]
        }

        image.gif


        目录
        相关文章
        |
        3月前
        |
        机器学习/深度学习 存储 算法
        LeetCode 题目 95:从递归到动态规划实现 不同的二叉搜索树 II
        LeetCode 题目 95:从递归到动态规划实现 不同的二叉搜索树 II
        |
        1月前
        |
        Python
        【Leetcode刷题Python】450. 删除二叉搜索树中的节点
        LeetCode上538号问题"把二叉搜索树转换为累加树"的Python实现,使用反向中序遍历并记录节点值之和来更新每个节点的新值。
        22 4
        【Leetcode刷题Python】450. 删除二叉搜索树中的节点
        |
        1月前
        |
        Python
        【Leetcode刷题Python】96. 不同的二叉搜索树
        LeetCode 96题 "不同的二叉搜索树" 的Python解决方案,使用动态规划算法计算由1至n互不相同节点值组成的二叉搜索树的种数。
        14 3
        【Leetcode刷题Python】96. 不同的二叉搜索树
        |
        22天前
        |
        算法
        LeetCode第96题不同的二叉搜索树
        文章介绍了LeetCode第96题"不同的二叉搜索树"的解法,利用动态规划的思想和递推公式,通过计算以任意节点为根的不同二叉搜索树的数量,解决了该问题。
        LeetCode第96题不同的二叉搜索树
        |
        1月前
        |
        算法 Python
        【Leetcode刷题Python】剑指 Offer 33. 二叉搜索树的后序遍历序列
        本文提供了一种Python算法,用以判断给定整数数组是否为某二叉搜索树的后序遍历结果,通过识别根节点并递归验证左右子树的值是否满足二叉搜索树的性质。
        14 3
        |
        1月前
        |
        Python
        【Leetcode刷题Python】538. 把二叉搜索树转换为累加树
        LeetCode上538号问题"把二叉搜索树转换为累加树"的Python实现,使用反向中序遍历并记录节点值之和来更新每个节点的新值。
        17 3
        |
        1月前
        |
        Python
        【Leetcode刷题Python】108. 将有序数组转换为二叉搜索树
        LeetCode上108号问题"将有序数组转换为二叉搜索树"的Python实现,通过递归选取数组中间值作为根节点,构建高度平衡的二叉搜索树。
        20 2
        |
        3月前
        |
        存储 算法 数据可视化
        LeetCode 题目 96:从动态规划、递归到卡塔兰数实现不同的二叉搜索树
        LeetCode 题目 96:从动态规划、递归到卡塔兰数实现不同的二叉搜索树
        |
        4月前
        |
        存储
        【LeetCode】剑指 Offer 54. 二叉搜索树的第k大节点
        【LeetCode】剑指 Offer 54. 二叉搜索树的第k大节点
        36 1
        |
        3月前
        |
        存储 算法 数据挖掘
        力扣173题:二叉搜索树迭代器(含模拟面试)
        力扣173题:二叉搜索树迭代器(含模拟面试)