java数据结构与算法刷题-----LeetCode96. 不同的二叉搜索树

news2024/11/19 14:27:09
java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846

很多人觉得动态规划很难,但它就是固定套路而已。其实动态规划只不过是将多余的步骤,提前放到dp数组中(就是一个数组,只不过大家都叫它dp),达到空间换时间的效果。它仅仅只是一种优化思路,因此它目前的境地和线性代数一样----虚假的难。

  1. 想想线性代数,在国外留学的学生大多数不觉得线性代数难理解。但是中国的学生学习线性代数时,完全摸不着头脑,一上来就是行列式和矩阵,根本不知道这玩意是干嘛的。
  2. 线性代数从根本上是在空间上研究向量,抽象上研究线性关系的学科。人家国外的教科书都是第一讲就帮助大家理解研究向量和线性关系。
  3. 反观国内的教材,直接把行列式搞到第一章。搞的国内的学生在学习线性代数的时候,只会觉得一知半解,觉得麻烦,完全不知道这玩意学来干什么。当苦尽甘来终于理解线性代数时干什么的时候,发现人家国外的教材第一节就把这玩意讲清楚了。你只会大骂我们国内这些教材,什么狗东西(以上是自己学完线性代数后的吐槽,我们同学无一例外都这么觉得)。

而我想告诉你,动态规划和线性代数一样,我学完了才知道,它不过就是研究空间换时间,提前将固定的重复操作规划到dp数组中,而不用暴力求解,从而让效率极大提升。

  1. 但是网上教动态规划的兄弟们,你直接给一个动态方程是怎么回事?和线性代数,一上来就教行列式和矩阵一样,纯属恶心人。我差不多做了30多道动态规划题目,才理解,动态方程只是一个步骤而已,而这已经浪费我很长时间了,我每道题都一知半解不理解,过程及其痛苦。最后只能重新做。
  2. 动态规划,一定是优先考虑重复操作与dp数组之间的关系,搞清楚后,再提出动态方程。而你们前面步骤省略了不讲,一上来给个方程,不是纯属扯淡吗?
  3. 我推荐研究动态规划题目,按5个步骤,从上到下依次来分析
  1. DP数组及下标含义
  2. 递推公式
  3. dp数组初始化
  4. 数组遍历顺序(双重循环及以上时,才考虑)
  5. dp数组打印,分析思路是否正确(相当于做完题,检查一下)

在这里插入图片描述

先理解题目细节

在这里插入图片描述

  1. 二叉搜索树,左子树都比根结点小,右子树都比根结点大,左右子树又各是一个二叉搜索树。而如果给我们一个数3.那么也就是让我们用①、②、③这3个结点构成二叉搜索树。
  1. 如果我们用①作根结点,那么②和③都大于①,只能在它右边,用②作根结点,那么①小于②只能放在左边,③大于②只能放在右边。
  2. 那么左右分多少个结点呢?我们发现,当我们截取②作为根,①、②、③这个序列,它左边的都小于它所有最终都会在它左边,同理右边的都在它右边。
  3. 令j = ②表示以②为根,共有i = 3个结点,那么②左边的,也就是j-1个 = 2-1 = 1个元素会被放在左子树。②右边的,也就是i - j= 3-2 = 1个元素会被放在右边
  1. dp数组存储:给你i个结点,有几种摆放方式可以构成二叉搜索树。下标i表示当前给我们多少结点可以用于构成二叉搜索树。
  2. i = 0时,只有一种方法组成二叉搜索树,就是什么都不摆,故,dp[0] = 1
  3. i = 1时,只有一个结点①组成二叉搜索树,只有一个结点,只有一种摆放方式,故,dp[1] = 1.
  4. i = 2时,有两个结点①和②可以组成二叉搜索树,所以我们有两种思路
  1. ①作为根结点,记为j,左边有j-1个元素比它小,右边有i - j个元素比它大
  2. ②作为根结点同理。
    在这里插入图片描述
  3. 而它的左右子树,有几个元素呢,你会发现一定比当前的i值小。都不大于2. 那么它们各有几种摆放方式呢?前面的dp数组构造时,已经考虑过了i = 0时,dp[0]=1, i=1时,dp[1]=1.两个相乘,就是以j为根的i个元素可以构造的二叉搜索树数量。最后将所有不同根结点情况相加即可。
解题思路
  1. 暴力求解的思想,就是利用回溯算法,不撞南墙不回头。
  2. 但是如果我们预先将其存储到dp数组,就可以直接通过dp, 获取数据,而不用枚举。典型的动态规划题目
动态规划思考5步曲
  1. DP数组及下标含义
  1. 我们要求出的是给你i个结点,可以构造出多少种不同二叉搜索树。显然dp数组中存储的就是i个结点,可以构造出多少种不同二叉搜索树。要求出谁的?显然是求出,i个结点可构造二叉搜索树数量。那么下标就是代表用几个结点构造二叉搜索树,很显然,只需要一个下标,也就是一维数组。
  1. 递推公式
  1. 因为0个结点只有一种摆放方式,1个结点也只有一种摆放方式,所以:F(0) = F(1) = 1;
  2. 对于其它数i,我们可以通过指定不同根结点,构造多种不同二叉搜索树。我们用j来表示当前用哪个结点代表根结点。例如i = 3,有1,2,3这3个数可以构造,当我们选其中一个数,例如1.那么必须保证左边都小于它,右边都大于它。也就是2和3必须在它右边,而没有比1小的数,因此左子树为空
  3. 因此,当我们选中j作为根结点后,它左边有j-1个数,右边有i-j个数。左边j-1个数可以构造dp[j-1]个不同二叉搜索树。右边i-j个数可以构造dp[i-j]个二叉搜索树。
  4. 当我们j的右边固定不变时,左边每变一次,都是一课全新二叉搜索树。同理,左边不变,右边变,也一样。所以他俩是相乘的关系。也就是以j为根节点,有dp[j-1] * dp[i-j]种不同二叉搜索树。
  5. 而当i = 3,我们有①,②,③这3个结点,j可以选择任意一个作为根结点,所以每种情况都得考虑,因此j = ① 和 j = ② 和 j = ③这3种情况的和才是dp[i]的值。故:F[i] = F[1-1] * F[i-1] + F[2-1] * F[i-2] + F[3-1] * F[i-3] + … + F[i-1] * F[i-i]
  1. dp数组初始化

在这里插入图片描述

  1. 数组遍历顺序(单重循环,无需考虑遍历顺序,一共就一维,哪里来的谁先谁后)
  2. 打印dp数组(自己生成dp数组后,将dp数组输出看看,是否和自己预想的一样。)

在这里插入图片描述

代码:时间复杂度O(n).空间复杂度O(n)

在这里插入图片描述

class Solution {
    public int numTrees(int n) {
        int dp[] = new int[n+1];//需要0到n的下标范围,因此需要n+1个元素
        dp[0] = dp[1] = 1;//0个结点和1个结点,只有一种摆放方式
        for(int i = 2;i<=n;i++){//剩下的,需要将不同结点作为根结点的情况加起来
            for(int j = 1;j<=i;j++){//j表示当前用谁当根结点
                dp[i]+=dp[j-1]*dp[i-j];//j当根结点,左边有j-1个元素,右边有i-j个元素
            }
        }
        return dp[n];//返回n个结点可以构成多少种二叉搜索树
    }
}

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

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

相关文章

day02_环境_基础

今日内容 零、复习昨日 一、工欲善其事必先利其器 二、GPT 三、Java是个啥 四、安装JDK 五、HelloWorld程序[重点] 六、编码规范 七、IDEA 八、Typora工具 附录: 单词 零、 复习昨日 复习 作业 一、工欲善其事必先利其器 看视频 PotPlayer 轻便,无级变速 内网通 局域网,聊天办公…

java应用中swagger使用

文章目录 前言使用依赖引入配置注解使用controller中注解实体类注解 页面展示 前言 现在前后端分离式开发&#xff0c;最头疼的部分就是接口文档了。最讨厌两种人&#xff0c;一种是不写接口文档的人&#xff0c;另一种则是让我写接口文档的人。实际上&#xff0c;我们有一款特…

【IC设计】ICer‘s 乾坤大挪移——FSM状态机

目录 理论解读状态机定义状态转移图Mealy和Moore型状态机推荐写“新两段式状态机” 设计实战可乐机两种state的FSM&#xff08;异步复位&#xff09;4种状态的one-hot状态机4种状态的同步复位状态机蓄水池问题 参考链接 理论解读 状态机定义 状态机简写为 FSM&#xff08;Fin…

基于域账户及西门子simatic logon的集中权限管理的实现(二)

上次我们完成了域环境及simatic logon服务器的搭建&#xff0c;今天我们将在wincc及HMI上进行组态&#xff0c;实现用域账户进行登录。 3.WINCC用户管理组态引文&#xff1a;博途工控人平时在哪里技术交流博途工控人社群 3.1 首先将要安装WINCC的服务器加入域。 3.2 在wincc…

SQL Server Management Studio (SSMS) 备份数据库

文章目录 前言一、在界面上操作二、使用sql 代码操作总结 前言 之前的文章记录过如何使用sqlserver复制远程数据库到本地。这里补充下如何使用SQL Server Management Studio (SSMS) 备份。 传送门&#xff1a;sqlserver复制远程数据库到本地 一、在界面上操作 在 SQL Server …

MyTinySTL 简单分析(二)--util.h exceptdef.h

目前在学习STL&#xff0c;看到一个开源的项目MyTinySTL&#xff0c;非常不错。想着照着这个代码自己敲一遍应该也能有些进步。然后就开始了学习过程。 首先分析的是vector 以下是由vector.h关联的所有头文件 本篇分析一下util.h &#xff0c; xxx 这里先来研究几个函数 st…

酒店订房小程序源码系统:帮您打造类似美团的酒店模式的小程序 带完整的安装部署教程

随着移动互联网的快速发展&#xff0c;小程序已经成为一种新型的应用形态&#xff0c;为各大行业提供了更加便捷的服务。其中&#xff0c;酒店预订小程序作为一种方便快捷的预订方式&#xff0c;备受用户青睐。小编给大家分享一款酒店订房小程序源码系统&#xff0c;旨在帮助您…

Ubuntu20.04-剪贴板

针对图形界面用户 1.两种方式 1.1 安装Parcellite 简单轻量级剪贴板管理器 sudo apt install parcellite 1.2 安装Gpaste 更强大的剪贴板管理器&#xff0c;包含历史记录和同步功能 sudo apt install gpaste

参加数据库活动,学习知识,领取奖品

去年12月1日我发了一篇关于数据库高可用的文章《我们的数据库需要什么样的HA&#xff1f;》&#xff0c;文中介绍了阿里云PolarDB MySQL通过了热备无感秒切技术&#xff0c;解决了HA场景下的故障探测、切换速度和切换体验的问题。文末提到了线上的PolarDB功能体验馆&#xff0c…

汽车研发测试大全

车研发中需要做的试验&#xff0c;这些试验都是保证我们的车能安全、稳定、可靠行驶的必要条件。主要包含以下内容&#xff1a; 一、整车试验项目 1.1整车可靠性试验 1.2 NVH试验 1.3 HVAC试验 1.4 EMC试验 1.5 化学分析试验 1.6 整车道路性能试验 二、零部件试验项目 …

特征工程之降维算法

数据降维简介 数据降维即对原始数据特征进行变换,使得特征的维度减少。 依据降维过程是否可以用一个线性变换表示,降维算法可以分为线性降维算法和非线性降维算法,下图展示了各种降维算法及其类别: 降维的必要性: 多重共线性和预测变量之间相互关联。多重共线性会导致解空…

【架构】docker实现集群主从扩容【案例3/4】

实现集群主从扩容 当整个集群扛不住流量的情况时&#xff0c;需要给集群扩容增加设备&#xff0c;由3主3从&#xff0c;扩为4主4从。实现&#xff1a; 示意图如下&#xff1a; 第一步&#xff1a;新创建两个节点&#xff08;redis-node-7&#xff0c;端口6387和 redis-node…

白码CRM快速实现报价转订单功能

某crm项目已经做到销售模块了&#xff0c;销售模块实现了从报价到销售单&#xff0c;再到财务模块的应收流程。但使用过程中发现不好用的地方&#xff1a;报价通过后客户下单&#xff0c;销售相关人员又要重新录入数据一样的销售单&#xff0c;觉得这样的操作比较繁琐&#xff…

若依基于sm-crypto实现前后端登录密码加密

上一节介绍了基于jsencrypt实现的密码加密解密登录功能&#xff0c;这次来介绍基于sm-crypto实现前后端登录密码加密&#xff0c;本次采用的是sm2进行的加密解密。 后端 首先从后端代码开始写起(因为公钥和私钥都是要从java代码中生成)&#xff1a; 首先需要引入sm-crypto的j…

【UE Niagara 条带粒子系列】01-初识条带渲染器

目录 效果 步骤 一、创建条带渲染器 二、增加粒子生成数量 三、设置条带粒子的初始宽度 效果 步骤 一、创建条带渲染器 1. 新建一个Niagara系统 选择“Simple Sprite Burst”模板 这里命名为“NS_RibbonRenderer” 打开“NS_RibbonRenderer”&#xff0c;删除“Sprite…

Kubernetes API 和流量控制:管理请求数量和排队进程

本文描述了我们最近遇到的一个真实案例&#xff1a;Kubernetes API 因其中一个集群中的大量请求而瘫痪。今天&#xff0c;我们将讨论我们如何处理这个问题&#xff0c;并提供一些关于如何预防它的提示。 高并发搞崩 Kubernetes API 一个非常普通的早晨&#xff0c;我们开始了…

KT148A语音芯在智能锁语音提示的优势在哪里成本还是性能

智能锁&#xff0c;已经广泛的应用于生活的各个场景&#xff0c;确实是一个好产品&#xff0c;我自己都在用&#xff0c;也很方便 而锁基本上都搭配有语音芯片或者蜂鸣器&#xff0c;低端的产品都是蜂鸣器&#xff0c;中端的产品基本都搭配语音芯片而智能锁方案中&#xff0c;…

智谱AI技术开放日:新一代基座大模型GLM-4及GLMs的发布

2024年1月16日&#xff0c;智谱AI举行了一次重要的技术开放日&#xff0c;发布了新一代基座大模型GLM-4和定制化的大模型GLMs。此次发布标志着智谱AI在人工智能领域的新一轮突破&#xff0c;进一步提升了大模型的性能&#xff0c;并降低了使用门槛&#xff0c;使得更多的人能够…

从界面探讨产品的卖点

背景 最近经常用这个平台来发布一些东西&#xff0c;总觉得体验不够好&#xff0c;毕竟这是号称是技术人员的聚集地&#xff0c;为何自己做的这个东西&#xff0c;好不好用&#xff0c;交互性咱们放到第二位&#xff0c;看了起码应该舒服&#xff0c;这应该是第一位的吧&#…

KubeSphere 核心实战之一【在kubesphere平台上部署mysql】(实操篇 1/3)

文章目录 1、登录kubesphere平台2、kubesphere部署应用分析2.1、工作负载2.2、服务2.3、应用路由2.4、任务2.5、存储与配置2.6、部署应用三要素 3、部署mysql3.1、mysql容器启动实例3.2、mysql部署分析3.3、创建mysql的配置3.4、创建mysql的数据卷pvc3.5、创建mysql工作负载3.6…