【算法练习Day34】整数拆分不同的二叉搜索树

在这里插入图片描述

​📝个人主页:@Sherry的成长之路
🏠学习社区:Sherry的成长之路(个人社区)
📖专栏链接:练题
🎯长路漫漫浩浩,万事皆有期待

文章目录

  • 整数拆分
  • 不同的二叉搜索树
  • 总结:

本期的两道题都有一些难度,不同的是第一道题看着可能有点想法,但是就是感觉差一点思路,以及代码不好实现,第二道题压根没什么思路,想不到它到底和动态规划的关系在哪,这是我对于初次做这两道题时候的想法。

整数拆分

343. 整数拆分 - 力扣(LeetCode)
在这里插入图片描述

整数拆分在leetcode上是一道中等难度的题,它的题目大意是将给定整数n拆解成若干数字乘积的形式,然后求出这些乘积中最大的一项是多少。我们首先要保证拆解出来的数字相加和应当等于原来的整数n。起初在做题的时候,我仅能想到用一个dp数组,且数组内部存取的应当是某个数字的最大乘积,进而一步步推出n的最大乘积,但是剩余的部分想不明白。我们来一起看看题解的解释,根据题解的思路来一步步推出。

dp数组的含义:dp数组含义之前已经说过了,它实际上就是求出第i个数字能够分解出来的数的乘积的最大值。

递推公式:这道题是将一个数字n分解成若干数字然后求最大乘积的题,那么有人就要问了那我们为什么还要用数组保存1-n的全部数字的整数拆分呢?关键点就在这里,我们要将该数分解,就要知道我们是怎么分解的,一个数可以被分解为j*(i-j),j是从1到i的数,例如说分解4,我们可以将其分解为:14,22,31,41,这么四种,也就是刚才的那个公式,j在循环里不断地增大,这样我么就可以使其算式发生变化。那么之前也说过,不一定将n这个整数分解成两个数相乘的形式,只要分解出的数相加等于n那么可以一直分解,例如10这个数我们可以分解为334,这也是合法的,那如果分解成这样我们要如何表示呢?这也是很重要的一点,我们可以想象334是由4乘上9得到的,根据dp数组的记忆我们可以写成是4*dp【9】,这是没毛病的,因为dp数组的定义就是某个数能被拆分后的最大乘积值,所以我们可以根据用dp数组来完成对于多个数字的拆分。

关于j的拆分

我们之前的上面写的公式都是假定j是根据循环变化而变化的值,而不是在递推公式里直接参与拆分的,那我们是否会落下一些情况呢?实际上并不会,每一次的j的变化而引起的数字拆分,是由上向下产生影响的!例如说10可以拆分为22222,那除了第一个2代表j之外,其余的2也可以分成11,但是不要忘记,第一个2也就是j的位置,早在前面j=1时候已经被拆成过11了,所以我们完全不要担心,后面能举出的j的拆分实例,均在j变得更小的时候,完成过类似于拆分的乘积运算了。

下一个我们需要在意的点是,由于递推公式写在j的变化之时,所以dp【i】是一定会随着j而改变的,那如果dp【i】之前已经找到了最大的值,我们还让他不停赋新值,不是会错过了吗,所以我们取一个最大值,即在dp【i】和j*(i-j)和j*dp【i-j}这三个值之中,取出最大值赋给dp【i】以达到保存更新最大值的效用。

dp数组的初始化:初始化就是dp【2】=2,为什么要这么写?因为0和1不能拆分,0就不用说了,1无法拆分成两个整数的相加。

遍历顺序:递推公式就可以得知了,我们推出当前的数字i的最大乘积,完全依赖于之前的数字,所以我们要从前向后遍历。

class Solution {
public:int integerBreak(int n) {vector<int>dp(n+1,0);dp[2]=1;for(int i=3;i<=n;i++){for(int j=1;j<i;j++)dp[i]=max(dp[i],max(j*(i-j),j*dp[i-j]));//dp[i-j]就相当于对i-j的拆分了}return dp[n];}
};

代码还是很简单的,但是想出思路要注意的点,还是蛮多的。

拆分的策略实际上就是固定前面的数字j,不拆分j而通过对于j的增加,而改变后面要拆分的值的策略。

不同的二叉搜索树

96. 不同的二叉搜索树 - 力扣(LeetCode)
在这里插入图片描述

这道题是很难的,可以说是困难题了。首先一定要审好题,这是一个求不同的二叉搜索树的题,是二叉搜索树而不是别的什么,强调这一点,是因为二叉搜索树是有一定的规律的。

这道题为什么说它难呢?递推公式比上一道题还难想,我们是根据分别列出n=1,n=2和n=3三种情况的二叉搜索树的形状,来找出一定的规律。n=1只有一种情况就是一个节点,n=2是一个八字形,即1开头的话那么就是有右子树2,2开头的话就是有一个左子树1,没有其他情况!因为这是搜索树,要严格按照搜索树的特点。n=3就分为1开头2开头和3开头三种情况,其中画图可知1和3开头的情况是和n=2的情况是一样的,两个八字形,而n以2开头是和n=1情况一样,是左右子树都平均的情况。这样算下来确实和题目案例对上了,n=3时候有五种情况,而这里我们是考虑二叉树的形状,而非二叉树节点值的不同,所以我们将n=3的以各个数字开头的情况和n=1和n=2的情况做了类比。

dp数组的含义:这里我们明确dp数组的含义实际上是用来保存数值i有多少种不同的二叉树。

递推公式

我们在上面已经分析了很多了,这里再来好好的看看递推公式的规律。 n=3的情况就是元素以1开头情况加上以2开头加上以3开头的情况。

而以1开头数量实际上等于右子树的有两个元素的情况*左子树有0个元素都情况

以2开头的数量等于右子树有一个元素的情况*左子树有1个元素的情况

以3开头的数量等于右子树有0个元素的情况*左子树有两个元素的情况

那么为什么是以乘法的形式得出的呢?而不是加法?我们假设左子树有五种元素情况,右子树有十种,那是不是左子树的每一种和右子树的十种都可以构造出不同的情况呢?所以我们这里用的公式就一定是乘法。

而有两个元素的情况就是n=2,也就是dp【2】,有1个就是dp【1】,0个就是dp【0】(这里看不懂,需要回想dp数组的含义是什么)

知道了这样的一个规律后,我们就可以推出dp【i】+=dp【j-1】*dp【i-j】

j-1是求左子树,i-j是求右子树,这里如果想不明白可以用n=3的各种情况带入,就能证明该公式一定是对的,那么为什么是+=而不是等于呢?这是因为我们要将各个情况都加进去,也就是1-n的所有开头情况加在一起,才是为n时的总二叉树个数。

dp初始化:dp的初始化就仅仅将dp【0】=1就可以了。0个节点也属于一种二叉树的情况。根据0

进而推出1,2,3等等。

遍历顺序:很明显也是一道从前往后遍历,因为要知道前面的情况才能得出n的情况。

class Solution {
public:int numTrees(int n) {vector<int>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];}
};

这就是本题的代码了。虽然本题代码很简短,但是代码很难想出。

首先能想到用动态规划做就有点难度,其次是规律十分难找,我们要能想出用前面的情况推出此时以1-n开头的各顶点情况能与之前的1到n-1的各种情况相呼应是很难的,再其次我们用以表示左右二叉树的j-1和i-j这也是很难想出来的,可能需要一定的数学推理。这些条件都使这道题变得毫无头绪,不知道入手点在哪里,自然就做不出来。

总结:

今天我们完成了整数拆分&&不同的二叉搜索树两道题,相关的思想需要多复习回顾。接下来,我们继续进行算法练习。希望我的文章和讲解能对大家的学习提供一些帮助。

当然,本文仍有许多不足之处,欢迎各位小伙伴们随时私信交流、批评指正!我们下期见~

在这里插入图片描述

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

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

相关文章

TypeScript -类 -类的基本定义

类的基本概念 类 就是对象的抽象&#xff0c;是对象的模板。 对象 就是类的一个具体实现。比如 【学生】是一个类&#xff0c;每个学生都有姓名、年龄两个属性&#xff0c;每个学生都有一个方法 sayHi()。【小明】是一个【学生】&#xff0c;也就是【学生】类的一个对象&#…

P2503 [HAOI2006] 均分数据

Portal. 考虑一种随机贪心做法。为了让方差尽可能小&#xff0c;要让每一组数的大小尽量接近。所以对于新的一个 a i a_i ai​&#xff0c;把它加入到当前的和最小的一组里。 为了提高正确性&#xff0c;让分组的可能性变多&#xff0c;我们随机 shuffle 这个序列&#xff0…

【httpd】 Apache http服务器目录显示不全解决

文章目录 1. 文件名过长问题1.1 在centos中文件所谓位置etc/httpd/conf.d/httpd-autoindex.conf1.2 在配置文件httpd-autoindex.conf中的修改&#xff1a;1.3 修改完成后重启Apache&#xff1a; 1. 文件名过长问题 1.1 在centos中文件所谓位置etc/httpd/conf.d/httpd-autoindex…

论坛搭建.

目录 一.配置软件仓库 二.安装http php miriadb 三.配置数据库 四.源码拖拽并解压 五.防火墙通过 六.浏览器安装测试 七.界面参数设置 一.配置软件仓库 1.进入仓库目录 cd /etc/yum.repos.d 2.创建仓库文件 vim local.repo 3.在 local.repo中写入:(粘贴的时候注意位…

C++递归实现验证⼆叉搜索树

C递归实现验证⼆叉搜索树 文章目录 C递归实现验证⼆叉搜索树题目链接题目描述解题思路C算法代码&#xff1a; 题目链接 98. 验证二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给你⼀个⼆叉树的根节点root&#xff0c;判断其是否是⼀个有效的⼆叉搜索树。 有效⼆…

吐血整理,Jmeter接口测试-项目案例场景,直接上高速...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 场景一&#xff1…

go 打包运行文件在windows,liunx运行

go 打包windows exe运行文件 1&#xff0c;如果设置过其他系统环境 就要重新设置设置系统环境$env:GOOS "windows"$env:GOARCH "amd64"2&#xff0c;在主函数同目录进行打包 指定main.go为入口主函数go build -o goweb.exe main.go比如src/main.go就在s…

如何优雅的开发?低代码搭建应用如此轻松

目录 一、前言 二、低代码平台体验简述 三、关于平台 四、场景及用户分析 五、产品分析 1、着重讲一下JNPF的编辑器 2、业务流程 六、最后&#xff0c;说些心里话 一、前言 低代码平台改变了应用交付和管理的模式&#xff0c;大幅缩减交付周期&#xff0c;最终帮助业务…

AcWing第 127 场周赛 - AcWing 5283. 牛棚入住+AcWing 5284. 构造矩阵 - 模拟+快速幂+数学

AcWing 5283. 牛棚入住 题目数据范围不大&#xff0c;直接暴力模拟即可 按照题目所说的意思即可。 #include <math.h> #include <stdio.h> #include <algorithm> #include <cstring> #include <iostream> using namespace std; const int N 1…

Docker底层原理:Cgroup V2的使用

文章目录 检查 cgroup2 文件系统是否已加载检查系统是否已挂载 cgroup2 文件系统创建 cgroup2 层次结构查看 cgroup2 开启的资源控制类型启用 cgroup2 资源控制设置 cgroup2 资源限制加入进程到 cgroup2 检查 cgroup2 文件系统是否已加载 cat /proc/filesystems | grep cgroup…

中缀表达式转后缀表达式

一、基本概念 中缀表达式&#xff1a;运算符都在运算数之间的表达式&#xff0c;也就是我们日常见到的表达式&#xff0c;包含括号。例如&#xff1a;(12)*5 后缀表达式&#xff1a;别称逆波兰式&#xff0c;指的是严格从左向右按照运算符出现的顺序进行计算&#xff0c;不包…

【ChatGPT瀑布到水母】AI 在驱动软件研发的革新与实践

这里写目录标题 前言内容简介作者简介专家推荐读者对象目录直播预告 前言 计算机技术的发展和互联网的普及&#xff0c;使信息处理和传输变得更加高效&#xff0c;极大地改变了金融、商业、教育、娱乐等领域的运作方式。数据分析、人工智能和云计算等新兴技术&#xff0c;也在不…

C语言 pthread_create

备注void *&#xff0c;最好添加返回值 原因&#xff1a;在实践中&#xff0c;虽然你的函数可能不需要返回任何值&#xff0c;但为了与 pthread_create 函数的预期函数指针格式相匹配&#xff0c;最好遵守函数指针所需的返回类型。这是一种良好的编程实践&#xff0c;确保你的代…

用起来顺手的在线表结构设计软件工具Itbuilder,与你共享

在线表结构设计软件工具需功能简洁&#xff0c;去除晦涩难懂的设置&#xff0c;化繁为简&#xff0c;实用为上&#xff0c;上手非常容易&#xff0c;这些itbuilder统统可以做到。 itbuilder是一款基于浏览器开发的在线表结构设计软件工具&#xff0c;借助人工智能提高效率&…

玩转视图变量,轻松实现动态可视化数据分析

前言 在当今数据驱动的世界中&#xff0c;数据分析已经成为了企业和组织中不可或缺的一部分。传统的静态数据分析方法往往无法满足快速变化的业务需求和实时决策的要求。为了更好地应对这些挑战&#xff0c;观测云的动态可视化数据分析应运而生。 在动态可视化数据分析中&…

io测试【FPGA】

// module io_def // 模块名字&#xff0c;参数&#xff0c;方法体 (input FPGA_CLK_50M_b5,input key1_k18,input key2_n17,input key3_n18,input key4_h17, //output led1_d15,output led2_c15,output led3_a12,output led4_b12,output beep_h13 //【注】最后一个参数不…

vue3学习(十四)--- vue3中css新特性

文章目录 样式穿透:deep()scoped的原理 插槽选择器:slotted()全局选择器:global()动态绑定CSScss module 样式穿透:deep() 主要是用于修改很多vue常用的组件库&#xff08;element, vant, AntDesigin&#xff09;&#xff0c;虽然配好了样式但是还是需要更改其他的样式就需要用…

3.12每日一题(有理函数不定积分)

两种方法&#xff1a; 1、拆项&#xff0c;然后分别加项减项拆&#xff0c;把分母降幂 注&#xff1a; x凑x的平方时前面要乘1/2 分子为x的平方可以分一个x去凑x的平方 2、联想三角有理函数公式&#xff0c;使用三角函数求解 用tant替换x&#xff1b;再通过二倍角公式降幂即可 …

QT: QLineEdit 密码模式、QLineEdit输入模式

setEchoMode(QLineEdit::Normal) 是一个函数&#xff0c;用于设置 QLineEdit 对象的输入模式。具体用法如下&#xff1a; lineEdit->setEchoMode(QLineEdit::Normal);该函数的作用是将 QLineEdit 对象的输入模式设置为“正常模式”&#xff0c;在此模式下&#xff0c;用户的…

数智领航未来∣2023契约锁企企通专题沙龙:数字建设,为企业高质量发展注入新动能

今年两会期间&#xff0c;“数字经济”是当之无愧的热词之一。中央经济工作会议提出&#xff0c;要大力发展数字经济&#xff0c;提升常态化监管水平&#xff0c;支持平台经济发展。 当前数据作为新型生产要素&#xff0c;价值尚未得到充分释放&#xff0c;需要疏通数据要素流通…