【leetcode】96. 不同的二叉搜索树(中等)

96. 不同的二叉搜索树

题目描述

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

示例 1:
在这里插入图片描述

输入:n = 3
输出:5

示例 2:

输入:n = 1
输出:1

提示:

  • 1 <= n <= 19

二叉搜索树

定义
二叉搜索树是一种节点值之间具有一定数量级次序的二叉树,对于树中每个节点:

  • 若其左子树存在,则其左子树中每个节点的值都不大于该节点值;
  • 若其右子树存在,则其右子树中每个节点的值都不小于该节点值。

示例:
在这里插入图片描述

一、动态规划

在这里插入图片描述
这种思想是比较容易的,如上图,我们可以把二叉树分为三部分:根节点、根节点的左子树、根节点的右子树,根节点分别是从1~n,左子树和右子树拥有的结点数是固定的,如n=3时,根节点为1时,无左子树,右子树有2、3;根节点为2时,左子树只有1,右子树只有3;根节点为3时,左子树有1、2,无右子树。

以 n = 3 为例:

  • 根节点为1时,无左子树,右子树有2、3:二叉搜索树数量即为2、3的二叉搜索树数量,即n=2时二叉搜索树数量;
  • 根节点为2时,左子树只有1,右子树只有3:二叉搜索树数量即为仅有1的二叉搜索树数量和仅有3的二叉搜索树数量相乘;
  • 根节点为3时,左子树有1、2,无右子树:二叉搜索树数量即为1、2的二叉搜索树数量,即n=2时二叉搜索树数量;
  • 将上述三种情况相加即为结果。
class Solution:
    def numTrees(self, n: int) -> int:  
        if n == 1:
            return 1
        nums = [1, 1]  # n个结点时二叉搜索树的数量,定义nums[0]=1, 显然nums[1]=1
        for i in range(2, n+1):  # i从2到n,为得到nums
            tmp = 0
            for j in range(1, i+1):  # j从1到n,计算nums[i]
                print(j)
                tmp += nums[j-1]*nums[i-j]
            nums.append(tmp)
        return nums[n]

简单优化一下

class Solution:
    def numTrees(self, n: int) -> int:  
        nums = [0 for i in range(n+1)]
        nums[0] = nums[1] = 1
        for i in range(2, n+1):  # i从2到n,为得到nums
            for j in range(1, i+1):  # j从1到n,计算nums[i]
                nums[i] += nums[j-1]*nums[i-j]
        return nums[n]

在这里插入图片描述

二、卡特兰数

参考:「算法入门笔记」卡特兰数

这里直接给出递推公式:
C 1 = 1 , C n = 4 n − 2 n + 1 C n − 1 C_1=1, C_n=\frac{4n-2}{n+1}C_{n-1} C1=1,Cn=n+14n2Cn1

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

friedrichor

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值