LeetCode0096.不同的二叉搜索树 Go语言AC笔记

23 篇文章 0 订阅

 时间复杂度:O(n²),空间复杂度:O(n)

解题思路

正常想法是动态规划,但是理解起来可能有一些别扭。如果是笔试就用卡特兰数解决。

我们可以先用递归的方法想一想,如果要想知道n个节点的二叉搜索树种类数,那么是不是应该尝试将所有节点都做一次根节点,然后它左面的节点就会成为它左子树节点,右面的节点就会成为它右子树的节点,这样就有了分而治之的思想。

接下来我们再尝试在它的左子树所有节点中重复以上的步骤,还是先找根节点,然后划分左子树节点和右子树节点,直到左子树或右子树节点数为0或1,说明只有一种情况,然后将左子树的情况数乘右子树的情况数就是根节点的情况数了。这样通过递归我们就能得到总的情况数。

但有没有发现这样递归浪费了许多无用功,也就是计算n个节点有多少种情况时可能第一次递归就计算出2个节点有2种,但是第二次递归其它子树时又算一遍2个节点有几种,这样重复计算会降低时间性能,所以我们考虑将计算过的n个节点情况数记录下来,这样下次就可以直接用而不需要重复计算了。

而这就有了动态规划的思想,先求出2个节点时的情况数,两个节点的情况数依赖于0个节点和1个节点的情况数,求完2个节点再去求3个节点时的情况数,3个节点的情况数依赖于0、1、2个节点的情况数……以此类推就可以求出n个节点时的情况数了。

AC代码

func numTrees(n int) int {
    G:=make([]int,n+1)//节点个数为n时的二叉搜索树种类数
    G[0],G[1]=1,1//初始化边界值
    //从节点数为2开始计算
    for i:=2;i<=n;i++{
        //第j个数作为根节点
        for j:=1;j<=i;j++{
            G[i]+=G[j-1]*G[i-j]//如果第j个数作为根节点,那么左子树一共有j-1个节点,右字数一共有i-j个节点,总的种类数就是二者种类数的乘积
        }
    }
    return G[n]
}

感悟

又一次被动态规划打败,不过代码写起来很简单,就看能不能屡明白吧……

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SwithunH

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

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

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

打赏作者

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

抵扣说明:

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

余额充值