[LeetCode]96. 不同的二叉搜索树

96. 不同的二叉搜索树

难度:中等

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

示例 1:

img

输入:n = 3
输出:5

示例 2:

输入:n = 1
输出:1

提示:

  • 1 <= n <= 19

通过次数147,278

提交次数210,767


解法1:卡特兰数

class Solution:
    def numTrees(self, n: int) -> int:
        return comb(2*n,n) // (n + 1)

解法2:动态规划

class Solution:
    def numTrees(self, n: int) -> int:
        dp = [0] * (n + 1)
        dp[0] = dp[1] = 1
        for i in range(2,n+1):
            for j in range(1,i+1):
                dp[i] += dp[j-1] * dp[i-j]
        return dp[n]

思路

这是一个经典的使用分治思路的题目。

对于数字 n ,我们可以 1- n 这样的离散整数分成左右两部分。我们不妨设其分别为 A 和 B。那么问题转化为 A 和 B 所能组成的 BST 的数量的笛卡尔积。而对于 A 和 B 以及原问题除了规模,没有不同,这不就是分治思路么?至于此,我们只需要考虑边界即可,边界很简单就是 n 小于等于 1 的时候,我们返回 1。

具体来说:

  • 生成一个[1:n + 1] 的数组
  • 我们遍历一次数组,对于每一个数组项,我们执行以下逻辑
  • 对于每一项,我们都假设其是断点。断点左侧的是 A,断点右侧的是 B。
  • 那么 A 就是 i - 1 个数, 那么 B 就是 n - i 个数
  • 我们递归,并将 A 和 B 的结果相乘即可。

其实我们发现,题目的答案只和 n 有关,和具体 n 个数的具体组成,只要是有序数组即可。

题目没有明确 n 的取值范围,我们试一下暴力递归。

代码(Python3):

class Solution:
    def numTrees(self, n: int) -> int:
        if n <= 1:
            return 1
        res = 0
        for i in range(1, n + 1):
            res += self.numTrees(i - 1) * self.numTrees(n - i)
        return res

上面的代码会超时。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值