力扣第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.rhkb.cn/news/487132.html

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

相关文章

【Windows11系统局域网共享文件数据】

【Windows11系统局域网共享文件数据】 1. 引言1. 规划网络2. 获取必要的硬件3. 设置网络4. 配置网络设备5. 测试网络连接6. 安全性和维护7. 扩展和优化 2. 准备工作2.1: 启用网络发现和文件共享2.2: 设置共享文件夹 3. 访问共享文件夹4. 小贴士5. 总结 1. 引言 随着家庭和小型办…

记录ubuntu22.04重启以后无法获取IP地址的问题处理方案

现象描述&#xff1a;我的虚拟机网络设置为桥接模式&#xff0c;输入ifconfig只显示127.0.0.1&#xff0c;不能连上外网。&#xff0c;且无法上网&#xff0c;用ifconfig只有如下显示&#xff1a; 1、sudo -i切换为root用户 2、输入dhclient -v 再输入ifconfig就可以看到多了…

guava 整合springboot 自定义注解实现接口鉴权调用保护

文章目录 一、简要概述二、实现过程1. pom引入依赖2. 自定义注解3. 定义切面4. 定义权限检查逻辑 三、注解使用四、运行结果五、源码放送 一、简要概述 Guava Cache是一个全内存的本地缓存实现&#xff0c;它提供了线程安全的实现机制。我们借助expireAfterWrite过期时间设置和…

MQTT消息服务器mosquitto介绍及说明

Mosquitto是一个开源的消息代理软件&#xff0c;支持MQTT协议&#xff08;消息队列遥测传输协议&#xff09;。MQTT是一种轻量级的发布/订阅消息传输协议&#xff0c;专为低带宽、不可靠网络环境下的物联网设备通信而设计。以下是关于Mosquitto服务器的一些介绍和说明&#xff…

React 组件中 State 的定义、使用及正确更新方式

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;React篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来React篇专栏内容React 组件中 State 的定义、使用及正确更新方式 前言 在 React 应用开发中&#xff0c;state …

DLL注入(AppInit_DLLs)

DLL注入(AppInit_DLLs) 一&#xff1a;概述 利用注册表进行dll注入&#xff0c;Windows操作系统的注册表默认是提供了AppInit_DLLs和LoadAppInit_DLLs两个注册表项的。打开我们的注册表编辑器&#xff0c;将要注入的DLL的路径字符串写入到AppInit_DLLs项目&#xff0c;然后将…

Spring Boot + Spring AI快速体验

Spring AI快速体验 1 什么是Spring AI主要功能 2 快速开始2.1 版本说明2.2 配置文件2.3 pom依赖2.3.1 spring maven仓库2.3.2 核心依赖 2.4 定义ChatClient2.5 启动类2.6 测试 3 参考链接 1 什么是Spring AI Spring AI是Spring的一个子项目&#xff0c;是Spring专门面向于AI的…

算法基础学习Day5(双指针、动态窗口)

文章目录 1.题目2.题目解答1.四数之和题目及题目解析算法学习代码提交 2.长度最小的子数组题目及题目解析滑动窗口的算法学习方法一&#xff1a;单向双指针(暴力解法)方法二&#xff1a;同向双指针(滑动窗口) 代码提交 1.题目 18. 四数之和 - 力扣&#xff08;LeetCode&#x…

通义千问sft-甄嬛对话

流程步骤 https://www.datawhale.cn/activity/110/21/76?rankingPage1 按照上面的流程&#xff0c;准备好数据之后就可以直接对7b的模型进行指令微调了&#xff0c;整个流程不是很复杂&#xff0c;操作起来比较方便。但是发布服务等了较长时间&#xff0c;以为出了bug 结果展…

1-6 ESP32控制LED灯

1.0 LED简介 LED是英文 "Light Emitting Diode" 的缩写&#xff0c;中文翻译为发光二极管。它是一种能够将电能转化为光能的电子元件。LED是一种半导体器件&#xff0c;在通电时会发出可见光。和传统的白炽灯泡或荧光灯相比&#xff0c;LED具有诸多优点&#xff1a;高…

前端成长之路:HTML(1)

每个网页都会有一个基本的结构标签&#xff08;也称为骨架标签&#xff09;&#xff0c;页面内容也是在这些基本标签上书写。 基本结构标签&#xff08;骨架标签&#xff09; <html></html>标签是HTML标签&#xff0c;是页面中最大的标签&#xff0c;被称为根标签…

细说敏捷:敏捷四会之回顾会

在前面的分享中&#xff0c;我们已经梳理了计划会、每日站会和复盘会的召开要点&#xff0c;本篇我们再对Scrum敏捷四大仪式中的最后一个会议仪式 - 迭代回顾会 进行探讨 回顾会的目的和作用 回顾会因为和复盘会一般都放在迭代的最后一天&#xff0c;而且通常安排是相邻在一起…

重生之我在异世界学智力题(1)

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言智力题题目&#xff1a;《奇怪的时钟…

【模型对比】ChatGPT vs Kimi vs 文心一言那个更好用?数据详细解析,找出最适合你的AI辅助工具!

在这个人工智能迅猛发展的时代&#xff0c;AI聊天助手已经深入我们的工作与生活。你是否曾在选择使用ChatGPT、Kimi或是百度的文心一言时感到一头雾水&#xff1f;每款AI都有其独特的魅力与优势&#xff0c;那么&#xff0c;究竟哪一款AI聊天助手最适合你呢&#xff1f;本文将带…

【时时三省】(C语言基础)结构体内存对齐练习题

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 练习一 这个输出结果是8 练习二 这个输出结果是16 练习三 这个输出结果是32 上面的输出结果都是根据结构体对齐规则来计算的

【python】UTF-8编码

# -*- coding: utf-8 -*-import sys reload(sys) # This reloads the system default encoding setup sys.setdefaultencoding(utf-8) # Set the default encoding to utf-8 print(sys.getdefaultencoding())写在最后&#xff1a;若本文章对您有帮助&#xff0c;请点个赞啦 ٩…

MySQL 性能优化详解

MySQL 性能优化详解 硬件升级系统配置优化调整buffer_pool数据预热降低日志的磁盘落盘 表结构设计优化SQL语句及索引优化SQL优化实战案例 MySQL性能优化我们可以从以下四个维度考虑&#xff1a;硬件升级、系统配置、表结构设计、SQL语句和索引。 从成本上来说&#xff1a;硬件升…

PCB设计规范

过孔设计 过孔盖油工艺&#xff08;也成为连塞带印&#xff09;&#xff1a;常规工艺、免费工艺&#xff0c;无特殊情况也建议使用此工艺。过孔大小建议直径在0.3mm-0.5mm之间。最省钱&#xff0c;效果最好。 非金属化槽孔 PCB制造商在加工非金属化槽孔时通常采用锣刀加工。最…

MVC基础——市场管理系统(二)

文章目录 项目地址三、Produtcts的CRUD3.1 Products列表的展示页面(Read)3.1.1 给Product的Model里添加Category的属性3.1.2 View视图里展示Product List3.2 增加Product数据(Add)3.2.1 创建ViewModel用来组合多个Model3.2.2 在_ViewImposts里引入ViewModels3.2.3 添加Add的…

vivado中,generate output product 和Create HDL wrapper的作用

generate output product 以zynq的ip核举例&#xff0c;没有generate output product之前&#xff0c;在ip source 什么也看不到。 但是同样的一个ip核&#xff0c;generate output product之后&#xff0c;会生成综合&#xff0c;布线和仿真文件&#xff0c;约束文件等等。 …