动态规划Leetcode96.不同的二叉搜索树

news/2024/10/3 23:45:43

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

解题步骤如下:

  1. 二叉搜素树的相关概念
  2. 寻找规律
  3. 思路建立
  4. 代码实现

1.二叉搜索树的相关概念

①:若左子树不空,则左子树所有节点的值均小于它的根节点的值。
②:若右子树不空,则右子树所有节点的值均大于它的根节点的值。
③:它的左右子树也分别为二叉搜索树。

2.寻找规律

当n=1时,二叉搜索树如图:
image
如图所示,n=1时,有1棵二叉搜索树

当n=2时,二叉搜索树如图:

  • [ ]

image
如图所示,n=2时,有2棵二叉搜索树

当n=3时,二叉搜索树如图:

当n=3时,我们可以仔细研究一下它们的情况。

  • 以1为头结点的二叉搜索树,都是左节点为0;且右节点布局与n=2时的布局一样(这里如果说数值都不一样云云,请记住题目只求种类不是具体的每一棵树)
  • 以3为头结点的二叉搜索树,都是右节点为0;且左节点与n=2时的布局一样
  • 以2为头结点的二叉搜索树,左右子树各有1个节点,形态也和n=1时只有一棵树的布局一样

那么可以上述规律可以整合为:
dp[3]=以1为头结点的搜索树数量+以2为头结点的搜索树数量+以3为头结点的搜索树数量

  • 以1为头结点的搜索树数量=左子树元素为0的搜索树的数量x右子树元素为2的搜索树数量
  • 以2为头结点的搜索树数量=左子树元素为1的搜索树的数量x右子树元素为1的搜索树数量
  • 以3为头结点的搜索树数量=左子树元素为2的搜索树的数量x右子树元素为0的搜索树数量

数量为0的搜索树数量为dp[0]
数量为1的搜索树数量为dp[1]
数量为2的搜索树数量为dp[2]

固有:dp[3]=dp[0]dp[2]+dp[1]dp[1]+dp[2]dp[0]
接下来把思路泛化成题目需要的样子

3.思路建立

1.定义dp数组含义
dp[i]为1到i个不同元素组成的二叉搜索树节点为dp[i];dp[n]就是题意要求的搜索树种数。
2.推导公式
由上述推导公式可知,我们需要明确头结点,左子树数量,右子树数量。故我们在这里设j作为头结点,那么左子树数量自然为(j-1)个,右子树数量为(i-j)个。
我们可以得公式:dp[i]=dp[j-1]*dp[i-j]
(可能会有朋友疑问为什么用相乘,打个比方说n=10的二叉搜索树,左子树情况有5种,右子树情况情况有8种,要想得出所有的情况是不是应该用相乘?)
当你用以上公式从1开始推导到n,你就会发现上述公式只是推导了某一个具体的i值,如果需要从1开始推导到n,我们需要做一个累加运算,从i=1开始运算,算完了i=1的值时,把它的结果累加到下一轮i=2的运算,这样我们计算到n时,就把1+2+3+......+n的值都没有差错地累加上了。

故最后的递推公式为dp[i]+=dp[j-1]*dp[i-j]
3.初始化
只需要考虑dp[0],若二叉搜索树左右子树任意一方为空,他们结果相乘为0是不合理的,故dp[0]=1。
4.遍历顺序
由递推公式dp[i]+=dp[j-1]dp[i-j]很容易看出,dp[i]是由比i小的状态数推导出来的,故是从小的数遍历到大的数(int i =1;i<=n;i++)
在i的循环底下,接着进行j的循环。j是头结点,从1的头结点开始,一直遍历到i为头节点的情况。固有(int j=1;j<=i;j++)
(不要懵逼为什么是i,我们定义的dp[i]里的i就是i个不同元素组成的搜索树的种类!)

4.代码实现

点击查看代码

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/67525.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

“!提醒:续购防毒”钓鱼网站套路

逛网站碰到套路:验证人机 -> 请点击开启网站通知验证是否为人机 -> 后面就开始不消停了,弹出下方内容,将用户引到未知网站 解决方法为 chrome 设置 -> 隐私与安全 -> 网站设置 -> 通知,将允许发送通知的陌生网站(网站名乱七八糟的)全部设置为不允许通知,…

在VS2022上安装pygame模块

一、安装 在vs2022中随便打开或生产一个python项目,找到最右边的“解决方案资源管理器”,并找到“python环境”,点击鼠标右键打开“查看所有python环境”打开以后找到下面的“在PowerShell中打开”,点击打开然后输入”pip install pygame“并等待安装即可 二、测试 输入以下…

SQLSTATE[42S22]: Column not found: 1054 Unknown column Color in field list

遇到 SQLSTATE[42S22]: Column not found: 1054 Unknown column Color in field list 错误,通常表示你在执行 SQL 语句时引用了一个不存在的列。这可能是由于拼写错误、表结构变更等原因导致的。 解决方法检查列名是否正确: 确认 Color 列是否存在,并且拼写正确。获取表结构…

P9752 [CSP-S 2023] 密码锁P8814 [CSP-J 2022] 解密

Guten Tag!Schn, dich zu sehen! 今天也是很懒惰的一天呢!所以今天三合一! 题目:[CSP-S 2023] 密码锁 题目描述 小 Y 有一把五个拨圈的密码锁。如图所示,每个拨圈上是从 $0$ 到 $9$ 的数字。每个拨圈都是从 $0$ 到 $9$ 的循环,即 $9$ 拨动一个位置后可以变成 $0$ 或 $8$,…

【STC15】实现printf()重定向的相关问题

本文前提:读者已经知道如何用STC15实现串口重定向的基础知识(大体思路和代码大意)。 如果不知道,请移步:《STC15单片机-串口打印》:https://blog.csdn.net/weixin_46251230/article/details/126679956问题1:uint8_t 数字增长显示错误 /* Private variables-------------…

解决wsl 安装出现Installing, this may take a few minutes… 时间长。且重新打开进入root用户问题

1. 现象 在安装wsl出现 Installing, this may take a few minutes… 等待时间过长,无法启动,或报错。且如果你重新打开终端,出现图二情况(直接进入root用户)。 很显然,你的系统已经正确安装,但是你却跳过了创建用户的步骤,因此,只需要创建一个新用户,并将其设定为默认…

数据库——DQL单表查询

DQL单表查询id name gender age score111111 刘一 女 20 NULL186222 陈二 男 30 90275933 张三 女 24 92266055 李十四 男 20 92134444 王五 女 18 92225573 赵十六 男 22 94一、简单查询(SELECT...FROM...) 1.查询所有字段(*) --SELECT * FROM 表名; SELECT * FROM class…

数据库——DDL数据库和数据表的基本操作

DDL 一、数据库的基本操作 1、创建(CREATE) --CREATE DATABASE/SCHEMA [IF NOT EXISTS] 表名[指定数据库的字符集]; --创建名为my的数据库 CREATE DATABASE my; CREATE SCHEMA my;--如果名为my的数据库不存在则创建,避免了当数据库存在而发生的错误 CREATE DATABASE IF NOT EXI…