- 博客(347)
- 收藏
- 关注
原创 leetcode 3259.超级饮料的最大强化能量
注意:这里额外要注意的是,如果选择一行一行的进行dp递归,产生的结果不一定对,因为如果只是针对一种饮料的出发进行处理的话,另一种饮料的最大能量就没有赋值了;所以,我们需要对这两个饮料同时进行递归才有效。这里的dp方程其实很简单,题目中已经给出了,要么就是相邻的最大能量+当前的能量值,要么就是下一种饮料隔开一瓶饮料的最大能量值+当前能量值,取最大值即可。不要忘记初始化res数组,让第一个饮料都赋值。
2024-11-03 17:29:55 149
原创 leetcode 763.划分字母区间
比如说,字符串前面有abc,这三个字母最后出现的地方就是这个位置,那么我们直接划分就行;但是如果说其中一个字母的最后坐标在远处,我们就需要以这个最远的坐标为主划分字符串。所以,在我们遍历的时候,需要每遍历一次字符串,就需要更新一次最远坐标。其实这个题目并不难,只需要分析出来每一个字母最后出现的坐标就行。我们根据字母最后出现的坐标数来判断最后划分的字符串。这里用了双指针的做法进行解答。
2024-10-28 10:52:10 261
原创 leetcode 739.每日温度
当我们碰到栈顶元素小于当前遍历元素的时候,我们就取出其中的坐标,然后跟当前的遍历的元素的下标相减,其实就是这个栈顶元素距离比它还高温度的天数了。其中当栈顶元素大于要遍历的元素的时候,我们就需要接着往后进行遍历,也就是在第一重循环的基础上再次遍历后面的数组有没有还小于的,直到我们找到再一次能够小于当前栈顶元素的值。思路二:其实和上面的思路大体上相同,但是唯一不一样的地方就是,我们上一个思路中的做法栈中存储的是元素值本身,这个思路中使用了栈元素为下标的值。再次记录栈中的元素有多少个就行了,也就是距离天数。
2024-10-15 11:24:03 313
原创 leetcode 3200.三角形的最大高度
既然需要在一个程序中体现两种可能,并且变量公用,我们所以需要单独写一个函数来解决.我们考虑两种情况:一种就是red在奇数层的,一种则是red在偶数层的情况。思路:其实模拟一下就可以了。在函数中进行模拟即可。
2024-10-15 10:25:00 106
原创 leetcode 79.单词搜索
有点麻烦,因为这里的dfs模型还不和那个灌水模型一样,灌水模型不需要关心回溯状态的事情,但是这里我们选择单词的时候,每一次独立的搜索,都必须保证其他的搜索不影响到这一次搜索。第二:参数值很多,从左到右依次是横纵坐标、word的对比位置、board数组、目标单词、存储结果的字符串、这一次大搜索里面的小搜索几个路径里有多少个符合单词条件的路径。第一:这里dfs的返回值是boolean类型,因为我们需要判断这次搜索是不是符合条件,有一个符合条件的就说明至少有一个搜索路径是符合题意的,所以需要用到返回值。
2024-10-11 19:35:54 224
原创 leetcode 292.Nim游戏
我们是先手的前提下,一共有4个石头,但是每个人只能一次拿其中的1-3个。在一共有4个石头的情况下,我们无论拿走几个,总会剩下对手可以拿到的范围的石头个数,我们必输;以此类推,当是8个,12个等等4的倍数的时候,我们可以按照4个4个的阶段进行解读,因为我们总是选择最优的解法,我们想赢,就必须把剩余的石子个数控制在4的倍数之外。所以,我们只需要把三种可能的结果剩余石头算出来,然后判断它们其中有没有不是4的倍数的石子个数,有一个就证明我们可以采取其中的几个策略来实施。
2024-10-11 19:29:52 319
原创 leetcode 22.括号生成
我们可以从括号的特点入手,括号我们知道都是成对存在的,那么无论多少对括号,其实第一个符号肯定是'(',而最后一个符号肯定是')'。因为这里dfs中我的'('个数是1,而')'个数是0,而不是1(有些人会想着把num2设置成1,其实也可以,改变一下满足条件即可)。第一,当‘(’的个数比‘)’的个数少的时候,证明我们没有正确的括号来匹配了,也就是无效,这时不能匹配括号;第二,当‘(’的个数要大于所给n的时候,说明我们的括号符号超过了,不能匹配;第三,当')'的个数要大于所给n的时候,同理,不能匹配。
2024-10-10 16:05:31 301
原创 leetcode 2073.买票需要的时间
第一,就是我们的队列到底存的是什么东西,这里我存放的是数组的下标,用下标来表示这个下标的数。当然,我们在进行-1操作的时候是对于原数组进行操作的,而不能另外开一个内存进行加减。第二:就是队列本身的问题,队列本身我们需要让它不为零,因为有可能出现全部都变成0而移走的可能性,所以需要判断一下。最后返回的时候,我们是在判断完它减完之后退出队列,所以我们在返回的时候需要额外的+1.还有就是标记数组,有点小题大用了,额外多开了一个数组长度的标志数组。这道题其实也就是一道模拟题而已,有一些小细节需要注意一下。
2024-09-29 18:52:20 363
原创 leetcode 1376.通知所有员工所需的时间
我们可以画出一个树进行模拟,其实题目的意思也就是让我们找出所用时间最大的一条路径而已,而所有员工所用的时间的权值是需要加在边上而不是节点上的,因为这里的叶子结点之后就没有人了,这个时候是不耗费时间的,所以我们需要明确的一点就是每个人所用的时间都需要加在父节点和子结点之间的枝头上。树的本质就是递归的,所以一旦见到了树的存储结构我们就需要往递归上去想。注意:我们在每次遍历完一个结点之后,一定是需要回溯的,因为如果不回溯你在此结点的结果,一定会影响其他的路径,这里大家需要细品。
2024-09-25 23:15:20 196
原创 leetcode 236.二叉树的最近公共祖先
思路一:作者的思路是按照数据结构中学的那样,按照层序遍历的遍历顺序给结点编号,然后每个结点的编号/2就是它的祖先节点,一直往上推,然后将其存储起来,然后在其中找到深度最深并且公有的那个结点就是最近的公共节点。思路是这样的:我们首先需要知道给出的两个结点在哪。如果是分别在两侧,那么当前的根节点就是他们的公共祖先。这个题的递归其实挺难想的,但是大体思路很明确。因为这个递归的过程使用并不与它的真实含义一致。这个方法放在数据量小的时候是可行的,但是数据量过大,就会时间超时,并且会浪费特别多空间,所以慎重取用。
2024-09-23 19:03:31 217
原创 leetcode 205.同构字符串
但是,我们要知道,哈希表的区分只是对于键的去重,而和元素的去重没有关系,所以我们开始在尝试直接用哈希表映射的时候,不同的字母可以映射一样的字母,这是和题目要求不匹配的。注意:这里说的字母是不仅仅包括26个字母,大家不要误会。还有一点就是,我们被标记的字母,再次遍历到有字母要映射它时,是不会放到哈希表里面去的,除了判断映射的字母是否和t字符串中的字符一致以外,还需要判断这个字符是否存在这个哈希表映射中。首先我们的题目要求我们每一个字母映射一个对应的字母,并且每个字母映射的字母不能一样,也就是严格的一一对应。
2024-09-23 17:45:00 243
原创 leetcode 437.路径总和III
因为这里面的元素中会考虑负数的存在,我们如果目前和大于目标和了之后,要是后面有负数可以加上变成目标和,我们岂不是错过了这一种可能呢?所以这个不能作为条件。我们可以首先遍历出树的全部结点,然后我们就从中一个一个拿出来进行深度优先搜索,也就是俗称的DFS。DFS的参数就定义为三个参数,一个参数用来存放结点,一个参数用来存放目前已经加了多少的和,还有目标和。还有就是结点有无的判断和是否是目标和的判断一定要分清先后,如果结点不存在在前,我们就需要先加上本结点的元素,然后判断目标和是否一致。
2024-09-20 18:34:10 382
原创 leetcode 106.从中序与后续遍历序列构造二叉树
思路:其实和根据前序遍历和中序遍历来构造二叉树是一样的思路,我们那道题首先确定的就是根节点,也就是说,根节点的位置是很重要的,我们需要知道根节点的位置在哪。我们可以看到,这两种遍历的前两个遍历都是中和左子树,我们就可以联想到,这两种遍历都是遍历一样的结点但是顺序不一样而已。我们从中找到根节点的位置,根据中序遍历,我们就知道了左右子树都是什么元素了。他们的后两个是一样的序列但是顺序不一样,我们从中找到根节点也就找到了左右子树在哪了。中序遍历中根节点的位置其实就是后序遍历右子树开始遍历的位置。
2024-09-19 16:07:17 364
原创 leetcode 392.判断子序列
两个指针分别指向两个字符串的首部,然后我们判断这两个指针现在指向的位置的字符是不是相同的;如果相同我们就两个指针同时移动;如果不同,我们就移动长度较大的那个字符串的指针向右。直至我们的指针有一个遍历完结束。画上计数器,如果我们的计数器的次数和子序列的长度是一样的,说明我们已经遍历完了子序列并且t中有一个子序列可以和s相同。特判:如果s的长度>t的长度,那么这个时候就是false;如果s是空的,那么就是true。
2024-09-19 15:47:41 374
原创 leetcode 105.从前序与中序遍历序列构造二叉树
我们知道,前序遍历的第一个结点就是根节点,我们可以在对应的中序遍历列表中找到与其对应的元素的下标,这个下标的往左一直到结束,就是左子树的部分,往右就是右子树的部分,所以我们就初步判断了这样的结论。我们截取除根节点以外的左子树部分,然后再从中找出一个类根结点,这个结点就是这棵树的左子树的第一个结点,同理,右子树也能找到这样的一个类根节点。顺着这个思路,我们知道了:通过递归的方法,以及切割数组的方法来判断每次子树的根节点,然后相连接起来,合成的就是一颗完整的树了,其本质就在于找各个子树的根节点。
2024-09-18 11:15:43 265
原创 leetcode 114.二叉树展开为链表
思路:前序遍历存储之后,然后令root的左右子树为null,再在root结点的右子树上边创建结点,边把存储的数往里面填。
2024-09-17 17:01:36 179
原创 leetcode 345.翻转字符串中的元音字母
我们再另外创建一个字符串,然后我们再遍历一遍字符串,如果没有标记(不是元音字母)就直接加入新的字符串中,如果有,就加入反转后的链表的下标对应的字符。作者的思路是按部就班的判断,首先遍历一遍字符串中的元音字母,找一个集合存储起来,然后用集合的方法进行反转,定义一个标志数组,如果是元音字母就标记。可以用双指针一个从头一个从尾开始遍历,双方指针都指向了元音字母的时候就交换,否则就继续遍历;
2024-09-17 16:43:12 254
原创 leetcode 199.二叉树的右视图
我们知道,在层序遍历的时候其实就是自上而下,自左而右的进行遍历树,但是,我们这里说的是右视图,其实就可以理解成,我们仿照层序遍历,自上而下,自右而左的遍历树,存储在一个存储集合的集合当中,第一层集合就代表树的层数,第二层的集合就相当于是本层从右到左的元素。
2024-09-16 17:05:22 399 1
原创 leetcode 605.种花问题
如果花坛数目是1,那么我们需要判断这一个位置中有没有花,在判断能不能放。有人会担心,如果这个时候花坛数目是1,但是n=2怎么办?题目中明确说明了,n<=花坛的数目所以这个时候n只可能是0或者1.当我们处理花坛的最左边或者最右边的时候,我们需要注意,这里不需要判断两边,只需要判断一端即可。题目本身很简单,只需要遍历数组即可。但是,需要注意边界的处理问题。如果n=0,那么这个时候是不需要插进花的,所以是true;如果花坛中的数目是0,那么就不行,返回false;只说注意点和处理边界问题。
2024-09-16 16:08:41 428
原创 leetcode 98.验证二叉搜索树
思路:二叉搜索树的一个特点就是,它中序遍历之后的序列是升序序列,我们就可以利用这一个特征来进行中序遍历,存储在一个集合当中,之后我们再进行判断这个集合是不是真正升序的就行了。
2024-09-14 10:43:33 406
原创 leetcode 108.将有序数组转换为二叉搜索树
思路一:在数据结构中,我们曾经学到过这样一个东西:二分搜索树(不是BST),这个树是根据二分搜索的搜索顺序而画出来的树。既然我们可以根据二分搜索的顺序来构建平衡二叉搜索树,那么我们就可以将原数组排成二分搜索此数组的顺序,这里用了集合容器作为额外空间存储。思路二:因为二叉搜索树的中序遍历正是一个升序的序列,所以我们可以任取一个结点,它的左边就是左子树,右边就是右子树。注意:我们在写树的创建函数时,一定要返回一个值,因为我们的结点在创建以后并不会归到树中,需要我们人为的赋给这个空指针结点才行,不然会不存在。
2024-09-13 18:56:03 344
原创 leetcode 1071.字符串的最大公因子
这需要我们看清题目了,题目说,是可以拼接成这两个字符串的最长字符串,ABC这个结果固然可以,但是并不是最长的,ABCABC既满足拼接后相等,也满足拼接后长度一致,是最长的母庸质疑。然后判断的时候,截取的字符串长度首先需要能够被两个字符串的长度都能整除才行,然后我们再各自拼接成和这两个字符串一样长度的新字符串,最后比较这两个字符串是不是分别和比较的字符串相同就可以了。因为如果出现这么一个最长的字符串,那么肯定就存在于两个字符串之中,并且是这两个字符串的子集。所以我们就直接在这两个字符串中枚举即可。
2024-09-13 17:32:36 308
原创 leetcode 1768.交替合并字符串
思路:和归并排序差不多的思路,在字符串上其实更简单。这次并不以数字大小进行比较然后移动指针,这次是指针交替移动,在长度相同的情况下,我们直接轮次指向就行。长度不同,首先按照长度相同的部分交替完,之后再加上哪个长度较大的字符串剩下的部分即可。
2024-09-12 18:25:58 176
原创 leetcode 994.腐烂的橘子
这道题就是这样传染病模型,我们实现BFS需要定义队列来实现,初始化的时候首先把0分钟就腐烂的橘子装入队列中,然后再进行BFS遍历比较方便。然后,又定义两个移动数组dy,dx用来判断周围的格子是否符合条件入队。因为BFS遍历比较简单,可以直接找模板,这里直接贴代码不详细讲了。注意:这里作者把0分钟腐烂的橘子在count数组定义中初始化了1,因为一开始创建count数组的时候初始值都是0,这样用于分辨。如果一个人生病了,他会传染给其他跟他接近的人,然后接近他的人感冒了就会传染给其他接近他们的人,依次类推。
2024-09-11 18:08:51 481
原创 leetcode 543.二叉树的直径
有人会认为只有经过根的那条路径才是最长的直径,其实不然,我们需要考虑更周到一点才行,只有遍历全部结点才能确定。用两个函数,一个函数用来获取当前结点的深度,一个函数用来遍历树的结点。这里的遍历方式采用了前序遍历。整体思路:其实就是对于树的每一个结点的左右子树相加,看看哪个结点的直径最大而已。这种方法其实就是把递归中的两个函数合在一起使用了,这样大大降低了时间复杂度。
2024-09-11 17:20:47 358
原创 leetcode 146.LRU缓存
然后,可以结合操作系统中最近最久算法的那个实例操作进行模拟,但是时间复杂度会O(n),因此并不是这道题的最优解,并且会因为时间限制通过不了,可以通过这个模拟方法复习操作系统,并且提升代码能力。如果只用哈希表进行模拟的话,需要开辟两个哈希表进行存储,一个装入数据,一个是记录数据key放入的次数。这个过程有点像自己在一堆书里拿书,就是灵神的那个题解思想,这里直接上代码。思路二:用双向链表,哈希表作为辅助。
2024-09-10 21:14:36 395
原创 leetcode 101.对称二叉树
思路二:可以递归同时进行,依次指向两节点其中的一个结点的左子树,和另一个结点的右子树,判断其某节点的左子树和另一个结点的右子树的元素是不是相同。一开始作者有这个思路,但是因为空指针异常,放弃了这个做法,是因为作者觉得根结点是特殊的,最多只有两个儿子,不需要颠倒左右子树;思路一:这里作者用了前序遍历的方法,并对前序遍历稍作了修改,对这个树的左右子树进行遍历并用集合进行了存储(即使是遍历到空结点也需要向里面添加null),然后比较两个集合中的元素是否一一对应。如出现一个不对应的地方,就直接返回false。
2024-09-09 17:39:57 427
原创 leetcode 23.合并k个升序链表
最后,数组在创建的时候不要根据题目的范围创建,需要首先计算出链表数组中的全部元素个数,然后创建相同数目的大小数组。思路:将链表数组中的val元素全部取出来,然后放在数组中进行排序,之后再用一重循环创造结点并连接即可。注意点:首先,链表数组可能是空的,需要特判;其次,链表数组中的链表可能是空的,需要特判。
2024-09-07 13:18:33 375
原创 leetcode 148.排序链表
如果投机取巧的话很简单,我们只需要对于链表中的元素体提取出来然后再排序重新赋值就行了。因为题目中并没有说需要改变结点的地址等等问题,因此我们可以直接对结点的值进行修改。
2024-09-06 11:23:42 164
原创 leetcode 138.随机链表复制
思路二:哈希表+模拟。这里其实也可以用哈希表进行记录,同时在遍历原链表的时候创建新的结点,不必要创建集合,这样可以减少一些空间复杂度。先将现链表创造结点然后填入原链表的结点值,之后指向与原链表一致,操作在现链表而不是指向原链表。最终,就是random指针,我们可以用集合的indexOf来判断指向结点的下标,然后指向即可。可以首先定义两个集合,一个集合用来存储原链表,一个集合用来存储现链表。之后,再处理next指针,i结点指向i+1结点即可。
2024-09-05 13:02:14 320
原创 leetcode 104.二叉树的最大深度
定义一个递归函数,里面有两个参数,一个是树结点,另一个就是记录树的层数(这里题目根结点为第一层),当我们遍历到目前的结点不存在的时候就返回它的层数,如果存在,我们让层数+1,然后分别遍历这个结点的左右结点,最后比较当前结点的左右子树谁的层数最多,取其中的较大数。其实树遍历的本质就是递归,我们需要合理运用这一特征。
2024-09-05 11:19:13 135
原创 leetcode 25.k个一组翻转链表
但是我们这里是k个一组,所以并不能下定结论这一组就是第一组,并且尾的指向并不明,因为下一组还没有进行翻转,所以我们又定义了一个集合list,只用来存储头和尾(存储的顺序不能颠倒),这样可以保证集合的长度是偶数,并能够有序的取出并修改指针。然后,当我们count==len-len%k的时候,也就是到最后一组未翻转前的尾元素时,我们需要记录它的下一个元素,因为它的下一个元素那一组是不足k个的一组,所以我们需要知道它的第一个结点,之后修改指针用来指向它。用出栈的元素指向栈顶的元素,就相当于是翻转了。
2024-09-04 11:39:36 437
原创 leetcode 94.二叉树的中序遍历
所以相应的,我们也可以自己定义一个栈维护结点,我们直接遍历从当前根结点开始,遍历所有的root的左子树,不断迭代,直至null,同时当里面入栈。当没有左子树之后就开始存储值,然后继续遍历当前结点的右子树,然后存储值,依次类推,递归之后再向上合并之后就是答案。根据这个特性,我们知道每一个结点都需要判断左子树和右子树的递归,这就需要写一个让每个遍历到的结点都能够进行递归左子树和右子树同时存储值的操作。很简单,我们定义一个递归函数,然后按照中序遍历的顺序就是先左子树,再中间结点,然后就是右子树的规律进行递归;
2024-09-03 09:25:57 367
原创 leetcode 24. 两两交换链表中的节点
很简单,我们只需要在1前面加上一个表头就行了,假设表头的元素值为-1,那么:-1->1->2->3,这样就解决了在头节点位置进行交换结点的问题了,之后汇总一下,就出来结果了。比如1,2,3,4,5这个时候我们只对于两个结点的指针地址修改是不够的,当我们交换3,4这两个结点的时候,我们就必须要处理2这个数到底指向谁,所以,为了迭代一致,我们需要用3个指针进行操作。在代码中,为什么tmp只是向前移动了一次呢?比如1,2这两个相邻的结点,在自然数中,2的后面肯定是3,用链表形式表示,也就有了1->2->3。
2024-09-03 08:39:10 327
原创 leetcode 240.搜索二维矩阵II
思路二:可以将矩阵转化为一个有序的二叉搜索树。其实就是把矩阵逆时针旋转45°看,这样就可以按照二叉搜索树的搜索方法来查询。选择其中一行进行遍历,然后对列的搜索进行二分搜索法搜索;或者选择其中一列进行遍历,然后对行的搜索进行二分搜索。
2024-09-02 15:39:46 335
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人