96. 不同的二叉搜索树 Python


一、题目描述

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

示例 1

在这里插入图片描述

输入:n = 3
输出:5

示例 2

输入:n = 1
输出:1

提示:1 <= n <= 19

二、代码

代码如下:

class Solution:
    def numTrees(self, n: int) -> int:
        result = [1, 1]  # n=0时 有1种情况, n=1时,也只有1种情况
        if n <= 1:
            return result[n]
        for m in range(2, n + 1):
            s = m - 1
            count = 0
            for i in range(m):
                count += result[i] * result[s - i]
            result.append(count)
        print(result[n])
        return result[n]

三、解题思路

本题需要找到所有可能的二叉搜索树的总个数,提供的二叉树结点是长度为n的连续自然数数组,我们希望能找到n取不同值时二叉搜索树总数,找到他们之间的一个规律,现本题解将发现规律进行展示:
我们假设f(n)为长度为n的连续自然数数组对应的二叉搜索树的总个数,则f(n)可以表示为:
先从最基础的情况开始看,
我们不难理解n=0(即空树)、n=1时二叉搜索树可能的情况只可能是1种(即f(0)=1,f(1)=1)
在n=2时我们也能很快知道二叉搜索树可能的情况只有2种(即f(2)=2)
当n=3时,我们可以选择任意的点作为根节点,然后在根节点左边的数被拿去构造左子树,在根节点右边的数被拿去构造右子树;
例如:n=3 时的数组为[1,2,3],
我们此时拿1作为根节点,则根节点左边的数[]拿去构造左子树,根节点右边的数[2,3]拿去构造右子树
此时左边的数[]长度为0,它只可能有1种情况,即f(0)=1;
而右边的数[2,3]长度为2,它则有可能有2种情况,即f(2)=2,
此时我们就可以用上之前求出来的基础结果了,因为左子树的构建和右子树的构建是独立互不影响的,所以他们所可能组成的结果总数为 f(0)f(2) = 2种
当然,因为我们是随机选择某个数作为根节点,所以还可能存在根节点为2,3的情况,以2为根节点为例,此时左边的数为[1],右边的数为[3],我们分别用它们去构建左、右子树,
此时左边的数[1]长度为1,它只可能有1种情况,即f(1)=1;
而右边的数[3]长度为1,它则有可能有1种情况,即f(1)=1;
则当根节点为2时,可能构成的结果数量为 f(1)*f(1) = 1种
同理,当我们选择3作为根节点时,可能构成的结果为 f(2)*f(0) = 2种
当我们加上以上所有结果后,我们就能知道n=3时的结果:
f(3) = f(0)f(2) + f(1)f(1) + f(2)f(0) = 2 + 1 + 2 = 5种
相同的,我们要求n=4时二叉搜索树的总数:
f(4) = f(0)f(3) + f(1)f(2) + f(2)f(1) + f(3)f(0) = 5 + 2 + 2 + 5 = 14种

所以当长度为n时,公式如下:
f(n) = f(0)*f(n-1) + f(1)*f(n-2) + f(2)*f(n-3) +… + f(n-3)*f(2) + f(n-2)*f(1) + f(n-1)*f(0)
最后化简就是我们求得的公式。
这样我们就可以从头开始慢慢计算后面的结果,每一次都会用上之前求得的答案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值