动态规划总结二 leetcode96

根据上一篇动态规划的做题步骤总结,再利用一个leetcode中等难度的题目进行讲解,96不同结构的二叉树。


96:不同结构的二叉树

题目:
https://leetcode-cn.com/problems/unique-binary-search-trees/
给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?
官方例子:
在这里插入图片描述
看到题目中能联想到n-1状态与n状态有关联的可以考虑使用动态规划。
1.首先确定数组的定义以及下标定义,一般来说都是定义f[i]为第i个时候存在多少种二叉树结构这样定义数组(第一步)
2.确定数组下标之后就是确定递推公式。先来分析一下n-1和n之间的关系。
这是2两个节点时候的二叉树:
在这里插入图片描述
这是三个节点时候的二叉树:
在这里插入图片描述
从图中我们可以找出一些规律来
是以新增节点3作为头结点,其他节点作为左右子树的分配情况,分别是
(1)图1、2中左子树为两个节点,右子树零个节点的分配情况
(2)图3,左子树和右子树都是一个节点的情况
(3)图4、5左子树为零个节点,右子树为两个节点的情况
所以针对于上面情况
(1)f[2]*f[0];
(2)f[1]*f[1];
(3)f[0]*f[2];
分析到这里,整道题目最难点递推公式已经可以解决了,那就是f[i] = f[j]*f[i-j-1]。(第二步结束)
3.数组进行初始化
零个节点时候就只有一种二叉树(空树)即f[0]=1;
一个节点时候就只有一种二叉树,即f[1]=1;
从f[2]开始就可以递推了,所以初始化只初始化前面两个。(第三步完成)
4.遍历顺序,通过前面分析除了要将f[i]从2到n进行遍历之后,还需要进行f[i]的取值计算即左右子树分配工作,这里的j取值是从0到i-1(因为头结点不用分配了。)所以需要两个循环。(第四步完成)
5.举一个例子验证一下。(第五步完成)

代码:

class Solution {
    public int numTrees(int n) {
        int[] f = new int[n+1];
        f[0] = 1;
        f[1] = 1;
        for(int i=2;i<n+1;i++){
            for(int j=0;j<=i-1;j++){
                f[i] += f[j]*f[i-j-1];
            } 
        }
        return f[n];
    }
}

其实还可以简化一下的,因为左右子树分配情况是对称的,只遍历到中间,前面的都乘2,如果子树是奇数个,中间只乘1就行了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值