leetcode 96. 不同的二叉搜索树

该文章介绍了一种使用C++实现计算不同结构的二叉搜索树数量的方法。通过递推关系S(i)=Σ[S(j-1)*S(i-j)],其中j从1到i,建立动态规划解决方案。初始条件是S(0)=S(1)=1。代码通过双重循环计算不同长度的二叉搜索树的组合数。
摘要由CSDN通过智能技术生成

纯净代码(c++)

class Solution {

public:

    int numTrees(int n) 

    {

        vector<int> S(n + 1, 0);

        S[0] = 1;

        S[1] = 1;

        for (int i = 2; i <= n; ++i) 

        {

            for (int j = 1; j <= i; ++j) 

            {

                S[i] += S[j - 1] * S[i - j];

            }

        }

        return S[n];

    }

};

一些知识点:

1.二叉搜索树具有的属性:每个节点的值比它的左子树的所有节点的值都要大,但比它的右子树的所有节点的值都要小。注意这个定义排除了树中存在值相同的节点的可能性。

2.笛卡尔积又叫笛卡尔乘积,是笛卡尔提出来的。 简单的说是两个集合相乘的结果。  假设集合A={b, c},集合B={0, 1, 2},则两个集合的笛卡尔积为{(b, 0), (b, 1), (b, 2), (c, 0), (c, 1), (c, 2)}。而笛卡尔积在本题代表了一个根节点的左右子树是什么

由上图可知:

//F(i,n)=S(i−1)*S(n−i),当前节点有多少种可能与两个子树有关,而子树又与子树的子树有关

//S(i−1)为以i为根的左子树, S(n−i)为其右子树

//后一项的值需要前面的值来得出,如F(5)需要F(1,2,3,4)。

个人注释:

class Solution {

public:

    int numTrees(int n) 

    {

        vector<int> S(n + 1, 0);//S[n]表示当长度为n时有多少种二叉搜索树

        S[0] = 1;//n不会为0,所以S[0] = 1表示的是空树,即nullptr

        S[1] = 1;//当长度为1,以1作为根节点只有一种可能,所以S[1] = 1

        for (int i = 2; i <= n; ++i) 

  //i表示长度,0,1对应的结果已经给出,从2开始,一步步推算到最大值

        {

            for (int j = 1; j <= i; ++j) 

//内层循环表示长度为i,以不同数值为根(注意要有等于i的情况,要判断i作为根时的情况),判断i的二叉搜索树有多少种情况

//S[j - 1]为以j为根节点的左子树,S[i - j]为以j为根节点的到i的右子树,内层循环整体等于模拟正整数i从1到i分别为头结点时左右子树的情况

//F(i,n)=S(i−1)*S(n−i),当前节点有多少种可能与两个子树有关,而这两个子树之前已经推算出来并存储在S中

            {

                S[i] += S[j - 1] * S[i - j];

//长度为n的情况下二叉搜索树的个数为分别取不同值为根进行判断,将值累加。内层循环每循环一次S[i]就累加,直到当前长度所有情况计算完毕,得到长度为i时的二叉搜索树的数量。

            }

        }

        return S[n];

    }

};

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值