力扣96不同的二叉搜索树详解

        最近在写动态规划的题目,这些题目的标签都标有数学,说来也是找规律题,但是这个规律真不是正常情况下可以找到的,即使看了解析有时候也写不出来,今天难得看了点解析就自己写出来的,因此分享一下这道题的想法和题解。

        废话少说,我们直接进入正题,首先要了解二叉搜索树的特点:根节点的左子树上所有节点都小于根节点,右子树上所有节点都大于根节点。然后就是找规律,以n=3为例:以1为根节点时,其余元素都大于1,左子树节点数为0,结果记为一次,右子树节点为2,在不考虑数值的话左右子树排列总数就等于n=2时候的值,即当1为根节点时结果数位arr[0]*arr[2];当2为根节点时,剩余节点一个大于2一个小于2,即左右子树各有一个节点,在不考虑值得情况下此时结果为arr[1]*arr[1];当3为根节点时,思路和1为根节点相同,只是所有节点都小于3,因此所有节点都在左子树上,右子树上的节点数为0,即结果为arr[2]*arr[0]。那么n=3能产生的不同二叉搜索树有arr[0]*arr[2]+arr[1]*arr[1]+arr[2]*arr[0]个。

        由题意可计算出arr[1]=1,arr[2]=2,arr[3]=5,代码如下:

        var numTrees = function (n) {
            let arr = new Array(n + 1).fill(0)//创建数组时创建n+1个,写的时候不会受到索引和n值差异的影响。
            arr[0] = 1, arr[1] = 1, arr[2] = 2, arr[3] = 5//当n=0时结果也可看成只有一次。
            for (let i = 4; i <= n; i++) {//从4开始向后求出其他值
                let m1 = 0//创建记录每个i时的总可能数
                for (let j = 1; j <= i; j++) {//遍历i时每一位作为根节点时候的可能
                    let m2 =1//记录每一位作为根节点时候的可能
                    if (j !== 1) {//当n不等于1时表示左右节点均有值
                        m2 = arr[j - 1] * arr[i - j]
                    } else {
                        m2 = arr[i - j]
                    }
                    m1 += m2
                }
                arr[i] = m1//将i时的值赋给数组。
            }
            return arr[n]//返回最后一个值即结果。
        };

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值