力扣第96题 不同的二叉搜索树

力扣第96题 - 不同的二叉搜索树


题目描述

给定一个整数 n,求以 1n 为节点组成的所有 不同的二叉搜索树(BST) 的个数。


题目分析

二叉搜索树的性质
  • 对于一个二叉搜索树,以 i 为根节点:
    • 左子树的节点值来自 [1, i-1]
    • 右子树的节点值来自 [i+1, n]
  • 左右子树分别是独立的子问题,即:左右子树的结构不会相互影响。
解法思路

本题的核心在于使用 动态规划卡特兰数公式 进行求解。


解法1:动态规划

定义状态

dp[i] 表示由 i 个节点组成的不同 BST 的个数。

状态转移方程
  1. 当以 j 为根节点时:
    • 左子树有 j-1 个节点;
    • 右子树有 i-j 个节点。
  2. 所以以 j 为根的 BST 数量为:
    d p [ j − 1 ] × d p [ i − j ] dp[j-1] \times dp[i-j] dp[j1]×dp[ij]
  3. j1i 遍历,累加所有可能的情况:
    d p [ i ] = ∑ j = 1 i d p [ j − 1 ] × d p [ i − j ] dp[i] = \sum_{j=1}^{i} dp[j-1] \times dp[i-j] dp[i]=j=1idp[j1]×dp[ij]
初始化
  • dp[0] = 1:空树是一种有效的 BST。
  • dp[1] = 1:只有一个节点的树只有一种结构。
实现步骤
  1. 创建数组 dp,大小为 n+1
  2. 初始化 dp[0]dp[1]
  3. 2n 遍历计算每个 dp[i]
  4. 最后返回 dp[n]

C语言实现(动态规划)

#include <stdio.h>
#include <stdlib.h>int numTrees(int n) {// 动态规划数组int* dp = (int*)malloc((n + 1) * sizeof(int));dp[0] = 1; // 空树dp[1] = 1; // 只有一个节点// 填充 dp 数组for (int i = 2; i <= n; i++) {dp[i] = 0;for (int j = 1; j <= i; j++) {dp[i] += dp[j - 1] * dp[i - j];}}int result = dp[n];free(dp); // 释放内存return result;
}int main() {int n = 5; // 测试输入printf("Number of unique BSTs for n = %d: %d\n", n, numTrees(n));return 0;
}

复杂度分析

  1. 时间复杂度

    • 双层循环:外层从 2n,内层从 1i
    • 总体复杂度为 O ( n 2 ) O(n^2) O(n2)
  2. 空间复杂度

    • 动态规划数组 dp 的大小为 O ( n ) O(n) O(n)

解法2:卡特兰数公式

公式推导

二叉搜索树的数量满足卡特兰数定义:
C n = 1 n + 1 ( 2 n n ) C_n = \frac{1}{n+1} \binom{2n}{n} Cn=n+11(n2n)

  • C n C_n Cn 是第 n 个卡特兰数。
  • 它表示从 1n 的节点所组成的不同 BST 的个数。
实现步骤
  1. 使用卡特兰数的公式直接计算:
    C n = ( 2 n ) ! ( n + 1 ) ! ⋅ n ! C_n = \frac{(2n)!}{(n+1)! \cdot n!} Cn=(n+1)!n!(2n)!

C语言实现(卡特兰数)

#include <stdio.h>// 计算阶乘
unsigned long long factorial(int n) {unsigned long long result = 1;for (int i = 1; i <= n; i++) {result *= i;}return result;
}int numTrees(int n) {// 卡特兰数公式unsigned long long numerator = factorial(2 * n);    // (2n)!unsigned long long denominator = factorial(n) * factorial(n + 1); // (n+1)! * n!return numerator / denominator;
}int main() {int n = 5; // 测试输入printf("Number of unique BSTs for n = %d: %d\n", n, numTrees(n));return 0;
}

复杂度分析

  1. 时间复杂度

    • 计算阶乘的时间复杂度为 O ( n ) O(n) O(n),整体复杂度为 O ( n ) O(n) O(n)
  2. 空间复杂度

    • 只使用常数空间,复杂度为 O ( 1 ) O(1) O(1)

示例解析

示例输入:
n = 3
示例输出:
Number of unique BSTs for n = 3: 5

对应的 5 种 BST 是:

  1. 根节点 1,右子树 [2, 3]
  2. 根节点 2,左子树 [1],右子树 [3]
  3. 根节点 3,左子树 [1, 2]
  4. 根节点 1,右子树 [3],中间插入 2
  5. 根节点 3,左子树 [2],中间插入 1

总结

  1. 动态规划 是解决本题的核心思想,通过状态转移方程,逐步构造所有可能的 BST 个数。
  2. 卡特兰数公式 是数学推导的简洁方法,适合需要快速计算的场景。
  3. 动态规划适合理解递归关系,公式计算适合处理较大规模的输入。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

List与Set、数组与ArrayList、ArrayList与LinkedList的区别

List 与 Set 的区别&#xff1a; 项ListSet重复允许重复的对象&#xff08;多个null也可以&#xff09;不允许重复的对象&#xff08;null也只能有一个&#xff09;有序性有序的。 保持了每个元素的插入顺序。即输出顺序就是输入顺序。 有序和无序都有。 HashSet&#xff1a;无…

Java的Mvc整合Swagger的knife4框架

Swagger的介绍 Swagger 是一个规范和完整的框架&#xff0c;用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。使用Swagger&#xff0c;就是把相关的信息存储在它定义的描述文件里面&#xff08;yml或json格式&#xff09;&#xff0c;再通过维护这个描述 文件可以去更…

01_Node.js入门 (黑马)

01_Node.js入门 知识点自测 从 index.js 出发&#xff0c;访问到 student/data.json 的相对路径如何写? A&#xff1a;../public/teacher/data.json B&#xff1a;./public/student/data.json C&#xff1a;../student/data.json <details><summary>答案</sum…

2024.12.5——攻防世界Training-WWW-Robots攻防世界baby_web

2024.12.5—攻防世界Training-WWW-Robots 知识点&#xff1a;robots协议 dirsearch工具 本题与第一道Robots协议十分类似&#xff0c;不做wp解析 大致步骤&#xff1a; step 1 打开靶机&#xff0c;发现是robots协议相关 step 2 用dirsearch进行扫描目录 step 3 url传参r…

springboot第84集:Java进阶之路, Netty

# kafka-map文件夹 cd /usr/local/kafka-map # 根据需求自行修改配置 vi application.yml # 启动 java -jar kafka-map.jar byte minByte -128; byte maxByte 127; 用于表示一个 8 位&#xff08;1 字节&#xff09;有符号整数。它的值范围是 -128&#xff08;-2^7&#xff0…

电脑无法识别usb设备怎么办?电脑无法识别usb解决方法

usb设备是我们常解除的外部操作以及存储设备&#xff0c;它可以方便用户数据传输以及操作输入。但在使用过程中&#xff0c;大家基本都碰到过电脑无法识别usb设备这种情况。这种情况下&#xff0c;我们应该怎么办呢&#xff1f;下面将为你介绍几种可能的原因和解决方法&#xf…

【学习总结|DAY014】Java面向对象高级-继承、多态

一、继承&#xff08;Inheritance&#xff09; 1. 概述 继承是面向对象编程的一种特性&#xff0c;允许我们定义一个类&#xff08;称为子类或派生类&#xff09;以继承另一个类&#xff08;称为超类或基类&#xff09;的功能。 2. 语法格式 public class Zi extends Fu {/…

【时间序列预测】基于PyTorch实现CNN_BiLSTM算法

文章目录 1. CNN与BiLSTM2. 完整代码实现3. 代码结构解读3.1 CNN Layer3.2 BiLSTM Layer3.3 Output Layer3.4 forward Layer 4. 应用场景5. 总结 本文将详细介绍如何使用Pytorch实现一个结合卷积神经网络&#xff08;CNN&#xff09;和双向长短期记忆网络&#xff08;BiLSTM&am…

筑起厂区安全--叉车安全防护装置全解析

在繁忙的工业生产领域中&#xff0c;叉车作为搬运工&#xff0c;穿梭于仓储与生产线之间。然而&#xff0c;叉车的高效运作背后&#xff0c;也隐藏着诸多安全风险&#xff0c;尤其是在那些空间狭小、物流繁忙的环境中。为了降低这些潜在的危险&#xff0c;叉车安全防护装置便成…

MS SQL SERVER服务自动停止解决

报错原因 电脑异常重启&#xff0c;导致 MS SQL server 服务启动后自动停止&#xff0c;在【计算机管理】-【事件查看器】-【windows日志】中进行查看系统错误日志&#xff0c;在【应用程序】下发现可能的错误信息&#xff1a; 传递给数据库 ‘model’ 中的日志扫描操作的日志…

网络安全信息收集(总结)更新

目录 重点&#xff1a; 前言&#xff1a; 又学到了&#xff0c;就是我们什么时候要子域名收集&#xff0c;什么时候收集域名&#xff0c;重点应该放前面 思考&#xff1a; 信息收集分为哪几类&#xff0c;什么是主域名&#xff0c;为什么要收集主域名&#xff0c;为什么要收…

使用 Postman 上传二进制类型的图片到后端接口写法

我们有的时候会有需求&#xff0c;就是通过 postman 传递二进制图片到后端接口&#xff0c;如下图&#xff1a; 那我们的 Java 接口需要怎么写呢&#xff1f; Spring Boot 接收这些数据的方式需要使用 RequestBody 注解来处理原始的二进制数据&#xff08;byte[]&#xff09;。…

如何在Maven项目中避免依赖包版本冲突

在复杂的Maven项目中&#xff0c;依赖管理是一个至关重要的方面。随着项目的增长和外部库的增加&#xff0c;不同依赖之间可能会引入相同库的不同版本&#xff0c;从而导致版本冲突问题。这不仅可能引发编译错误&#xff0c;还可能导致运行时异常或难以调试的行为。本文将探讨几…

Java Web 7 请求响应(Postman)

前言&#xff08;SpringBoot程序请求响应流程&#xff09; 以上一章的程序为例&#xff0c;一个基于SpringBoot的方式开发一个web应用&#xff0c;浏览器发起请求 /hello 后 &#xff0c;给浏览器返回字符串 “Hello World ~”。 而我们在开发web程序时呢&#xff0c;定义了一…

pytorch多GPU训练教程

pytorch多GPU训练教程 文章目录 pytorch多GPU训练教程1. Torch 的两种并行化模型封装1.1 DataParallel1.2 DistributedDataParallel 2. 多GPU训练的三种架构组织方式2.2 数据不拆分&#xff0c;模型拆分&#xff08;Model Parallelism&#xff09;2.3 数据拆分&#xff0c;模型…

【opencv入门教程】9.视频加载

文章选自&#xff1a; 一、VideoCapture类 用于从视频文件、图像序列或摄像头捕获视频的类。函数&#xff1a;CV_WRAP VideoCapture();brief 默认构造函数CV_WRAP explicit VideoCapture(const String& filename, int apiPreference CAP_ANY);brief 使用 API 首选项打开…

海外的bug-hunters,不一样的403bypass

一种绕过403的新技术&#xff0c;跟大家分享一下。研究HTTP协议已经有一段时间了。发现HTTP协议的1.0版本可以绕过403。于是开始对lyncdiscover.microsoft.com域做FUZZ并且发现了几个403Forbidden的文件。 &#xff08;访问fsip.svc为403&#xff09; 在经过尝试后&#xff0…

阿里内部正式开源“Spring Cloud Alibaba (全彩小册)”

年轻的毕业生们满怀希望与忐忑&#xff0c;去寻找、竞争一个工作机会。已经在职的开发同学&#xff0c;也想通过社会招聘或者内推的时机争取到更好的待遇、更大的平台。 然而&#xff0c;面试人群众多&#xff0c;技术市场却相对冷淡&#xff0c;面试的同学们不得不面临着 1 个…

乘上 SpringBoot 东风,广场舞团掀起律动热潮

2 系统开发环境 2.1 Java技术 Java是由Sun公司推出的一门跨平台的面向对象的程序设计语言。因为Java 技术具有卓越的通用性、高效性、健壮的安全性和平台移植性的特点&#xff0c;而且Java是开源的&#xff0c;拥有全世界最大的开发者专业社群&#xff0c;所以Java的发展迅速。…

【PlantUML系列】状态图(六)

一、状态图的组成部分 状态&#xff1a;对象在其生命周期内可能处于的条件或情形&#xff0c;使用 state "State Name" as Statename 表示。初始状态&#xff1a;表示对象生命周期的开始&#xff0c;使用 [*] 表示。最终状态&#xff1a;表示对象生命周期的结束&…