![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
代码随想录训练营
文章平均质量分 76
.wsy.
这个作者很懒,什么都没留下…
展开
-
代码随想录算法训练营day61丨一刷总结
然后因为递归函数其实是用栈来实现的,所以说前中后序的遍历是可以用栈来实现的。动态规划真的是进行了好多好多章节,真的是做题做到崩溃了都,它有编辑距离问题,背包问题,股票问题都很复杂,我感觉最复杂的最难搞的其实是dp数组的定义,如果对dp数组的定义有很得到的见解的话,其实它的推导公式就会变得简单一些,但是关键这个dp数组的定义有时候就,可能我比较傻,反正就是想不到,但是最后文章里面也给出了dp数组的定义通常就是题目要求解的问题,其实做的几道题里面大多数都是这样,当然也有例外,还是得多做题积累。原创 2024-03-15 23:43:08 · 366 阅读 · 0 评论 -
代码随想录算法训练营day60|第十章 单调栈part03
这道题还有一个需要注意的点是。这道题的辅助数组储存的是每个柱子左右边第一个小于当前柱子高度的柱子的下标,而接雨水找的是左右两边的最值,最值可以通过max函数来实现,但具体到第一个小于当前柱子高度这种,那就只能再嵌套一个循环了,嵌套使用的是while循环,逻辑是从当前位置向它的左/右边去找,一直找到下标为零处/末尾处,所以必须要先初始化最初用到的值,初始化成多少也是有讲究的,最左端的下标值没有左边的元素,所以初始化下标为-1,这样不仅合乎逻辑,也能用同样的公式来推导出矩形的面积,好吧其实有点废话了。原创 2024-03-15 23:09:06 · 385 阅读 · 0 评论 -
代码随想录算法训练营day59|第十章 单调栈part02
每次如果遍历到大于栈顶元素的值,那就先记录一下当前的栈顶元素,然后再弹出这个栈顶元素,然后再判断一下这个栈里面是否还剩有元素,如果剩有元素,证明可能构成一个凹槽用来盛水,那就要计算盛水的水量,先计算水的高度,水的高度取遍历的柱子的高度和栈顶高度的最小值再减去之前储存的那个栈顶元素,水的宽度当然就是遍历的元素的下标和现在栈顶元素的下标的下标差再减一(因为求的是中间的部分,用来盛水的那种宽度),相乘求得水量;注意这回 i 代表的不直接是nums的下标,而更多的是遍历次数,取余之后才会是nums下标。原创 2024-03-13 22:33:26 · 966 阅读 · 0 评论 -
代码随想录算法训练营day58|第十章 单调栈part01
如图所示,一旦遍历到的元素大于栈顶元素,那就没办法维持顺序(从栈顶到栈底单调递增了),所以想要放入当前元素,需要将栈顶元素弹出,直到栈顶元素再也不小于当前遍历到的元素为止或栈为空,每弹出一个元素,在这道题中就相当于找到了之后比它温度大的一天,于是就要同步更新res数组记录二者的距离,这时候就凸现出单调栈存入下标的必要性了,这样可以直接操作对应下标的res值,等于当前遍历到的元素下标减去弹出的下标。就可以了,如果需要使用对应的元素,直接T[i]就可以获取。大家可以读题,思考暴力的解法,然后在看单调栈的解法。原创 2024-03-13 19:45:23 · 432 阅读 · 0 评论 -
代码随想录算法训练营day57|第九章 动态规划part17
初始化时候,考虑当i 和j 相同的情况,由于递推公式:dp[i][j] = dp[i + 1][j - 1] + 2,看出递推公式是计算不到 i 和j相同时候的情况。除此之外,每次 j 的遍历里面第1次执行dp[i][j] = dp[i + 1][j - 1] + 2,所用的之前的值dp[i + 1][j - 1]实际上为0( j 从 i + 1开始遍历,每次恰好错过初始化这个值),所以在仅有两个元素的时候,如果这两个元素恰好相等或不相等,都能按照这种递推方式来推导当前值。注意还要用res来捡拾结果。原创 2024-03-13 00:12:30 · 926 阅读 · 0 评论 -
代码随想录算法训练营day55|第九章 动态规划part16
做一个总结吧。原创 2024-03-12 21:57:26 · 997 阅读 · 0 评论 -
代码随想录算法训练营day54|第九章 动态规划part15
t[ j ]) dp[ i + 1 ][ j + 1 ] = max(dp[ i ][ j + 1 ], dp[ i + 1 ][ j ]),但实际上已经确定了s串是长度较小的字符串,i往前挪所得到的最大公共子序列长度一定会变小(而且这道题是外层遍历的s串,所以如果可以最终返回true,i之前的字符一定已经找到对应的了),所以dp[ i ][ j + 1 ]一定小于dp[ i + 1 ][ j ]。dp[i][j]是以i-1为结尾的s子序列中出现以j-1为结尾的t的个数为dp[i][j]。原创 2024-03-11 23:06:01 · 483 阅读 · 0 评论 -
代码随想录算法训练营day53|第九章 动态规划part14
如果text1[i - 1] 与 text2[j - 1]相同,也就是找到了一个公共元素,故而也就要在原来的基础上加一,所谓原来的基础也就是左上角的dp[i-2][j-2],为什么要让指向两个字符串的指针同时往回退一个就储存着原来的基础呢,这是因为既然text1的(i - 1)处和text2的(j - 1)处所对应的元素相等,那就要往前倒,看[0, i - 2]和[0, j - 2]范围内的情况是怎样的,所以dp[i][j] = dp[i - 1][j - 1] + 1;1143.最长公共子序列。原创 2024-03-10 18:37:52 · 963 阅读 · 0 评论 -
代码随想录算法训练营day52|第九章 动态规划part13
明确了这一点,要理解需要两层嵌套遍历就容易一点,要依次更新每一个dp[i],就必须每次都遍历一整遍前面的nums,一旦发现有小于当前nums[i]的,就证明当前nums[i]可以作为原来(以nums[j]为结尾的)子序列的新结尾,并且试图更新dp[i]的值,注意外层遍历从下标1开始(0前面没有元素,不可以用来更新dp[0]),内层循环从0开始到 i 前结束(遍历所有可能成为 以nums[i]结尾子序列的倒数第二个值 的数)。本题相对于昨天的动态规划:300.最长递增子序列 最大的区别在于“连续”。原创 2024-03-10 12:32:08 · 853 阅读 · 0 评论 -
代码随想录算法训练营day51|第九章 动态规划part12:买卖股票总结
题目中每天的状态可以是:今天持有股票,所以继续持有或者直接卖出;今天不持有股票,且不在冷冻期前提下,选择购买或者不购买,在冷冻期前提下,只能不购买。相对122.买卖股票的最佳时机II ,本题只需要在计算卖出操作的时候减去手续费就可以了,代码几乎是一样的,可以尝试自己做一做。本题加了一个冷冻期,状态就多了,有点难度,大家要把各个状态分清,思路才能清晰。一个路子,我选择在买入的时候同时减去fee,其他一致。文章里面是按照分成四种状态来分析的——309.最佳买卖股票时机含冷冻期。122.买卖股票的最佳时机II。原创 2024-03-08 13:26:58 · 801 阅读 · 0 评论 -
代码随想录算法训练营day50|第九章 动态规划part11
进一步,多次交易的本钱是dp[i-1][0],这个值是经历多次交易得到的,而这次对于第二次持有股票的递推公式是dp[i][2] = max(dp[i-1][2], dp[i-1][1]-prices[i]),它的本钱是dp[i-1][1],这个值是只(最多)经历过一次交易得到的(dp[i][0]以及dp[i][1]的推导是根据交易一次股票的前提推导的),故而它必然只能是第二次交易(最多)。这道题一下子就难度上来了,关键在于至多买卖两次,这意味着可以买卖一次,可以买卖两次,也可以不买卖。原创 2024-03-07 22:45:51 · 1057 阅读 · 0 评论 -
代码随想录算法训练营day48|第九章 动态规划part10
很显然递推公式是:dp[i][0] = max(dp[i - 1][0], -prices[i]) 和 dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0])。故而有递推公式:dp[i][0]=max(dp[i-1][0],dp[i-1][1]-prices[i]) 和 dp[i][1]=max(dp[i-1][1],dp[i-1][0]+prices[i])。贪的是最小价格和最大差值(当然是当天或这天后的价格与最小价格的差值),代码很好懂。原创 2024-03-06 21:14:01 · 410 阅读 · 0 评论 -
代码随想录算法训练营day47|第九章 动态规划part09:198.打家劫舍、213.打家劫舍II、337.打家劫舍III
打家劫舍是DP解决的经典题目,今天就是打家劫舍的一天,这个系列不算难,大家可以一口气拿下。198.打家劫舍首先,dp[i]表示考虑下标i(包括i)以内的房屋,最多可以偷窃的金额。如果偷了当前房间,那么当前的金额就是偷前i-2个房间得到的最大金额+本房间金额,如果没偷,那么当前金额就是偷前i-1个房间得到的最大金额,那么递推公式就很明确了,dp[i] = max(dp[i - 2] + nums[i], dp[i - 1])。原创 2024-03-06 17:13:01 · 866 阅读 · 0 评论 -
代码随想录算法训练营day46|第九章 动态规划part08:139.单词拆分、背包问题总结
139.单词拆分回溯——这道题用回溯的做法也能实现,但是需要使用memory数组来记录-以startIndex为起始点是否能保证之后(也包含当前点)全部字符都恰好在wordSet中找到对应的单词,这样有记忆的寻找能减少大量重复搜索,而直接回溯会超时。使用bool作为返回值表示不是一直找而是找到一组即可。完全背包——首先还是要说明想要在数组中找到某个元素,需要将数组存储为set,又因为不用排序,所以unordered_set就够用。原创 2024-03-06 09:45:51 · 859 阅读 · 0 评论 -
代码随想录算法训练营day45|第九章 动态规划part07:70. 爬楼梯 (进阶)、322. 零钱兑换、279.完全平方数
这道题本质上是完全背包求最大值的变种,所以自然无关背包和硬币的遍历顺序,主要是初始化和递推公式比较新颖。因为是求最小硬币数量,所以递推公式自然是 dp[j] = min(dp[j - coins[i]] + 1, dp[j]) ,而如果要这么求dp数组的值,势必要将每个dp数组的值初始化为INT_MAX,而因为最终还是要改写dp数组的值的(无论哪个总面值,想要得到最小硬币数,就必须利用过dp[0]的值,这时得到的结果必然是1),所以dp[0]需要初始化为0,理解当然是很容易,0元就是0个硬币。原创 2024-03-05 17:02:32 · 392 阅读 · 0 评论 -
代码随想录算法训练营day44|第九章 动态规划part06:518. 零钱兑换 II、377. 组合总和 Ⅳ
如果先遍历背包容量,那么求解容量 j 的方法数的时候可能出现同组合不同排列的情况(例如,容量6,可能遇到把{1,5}和{5,1}同时算入的情况,因遍历了全部物品,所以之前的值势必会将这个容量的全部可能情况都考虑在内,故而在填充 dp[6] 的时候,遍历到物品1时会+=dp[5],遍历到物品5时会+=dp[1],而dp[5]必然包含{5}、dp[1]必然包含{1}的情况,所以就相当于算了两遍{1,5},再装入多个物品时同理)。这道题就是典型的完全背包求排列数问题,直接套即可。518. 零钱兑换 II。原创 2024-03-05 15:30:03 · 923 阅读 · 0 评论 -
代码随想录算法训练营day40|第九章 动态规划part03
这道题真的好难想到。主要是考虑到二叉搜索树的特点(左小右大),有n个元素的时候,要考虑1-n中每个元素作为根节点的情况,对于其中一种情况,一旦确定了根节点,那么它的左右子树的节点是什么就是确定的了,而本身的搜索树的种类数就是左右子搜索树种类数相乘,而左右子树的种类数量是由它的节点个数k确定的,也就是dp数组之前已经得到的有个k元素的时候二叉搜索树的数量,虽然这两次情况的具体的数不同,但是因为都是一段同样长度的连续递增的序列构成的二叉搜索树,故而根据搜索树的性质可见是相等的。96.不同的二叉搜索树。原创 2024-02-29 22:49:04 · 384 阅读 · 0 评论 -
代码随想录算法训练营day39|第九章 动态规划part02
本题大家掌握动态规划的方法就可以。数论方法 有点非主流,很难想到。这道题其实也很简单,dp数组的意义也很容易想到,主要是dp数组初始化可能会有难度,考虑到递推公式是到达当前格子的方法=到达顶头上面的格子方法+到达左边格子的方法(因为只能往下走或往右走,故而只能从上边来或从左边来),需要初始化最左边的一列和最上边的一行为1(因为到达最上边的任意一个格子的方式只能是从开始处一直往右走,同理最左边)。原创 2024-02-29 07:59:50 · 565 阅读 · 0 评论 -
代码随想录算法训练营day38|第九章 动态规划part01
这道题就是要考虑到dp数组的意义是每一层的方法数,这样问题就迎刃而解,当前楼层的方法数就是前一层的方法数+前前一层的方法数(因为这道题一次只能上一个或两个台阶,所以只有这层楼的前一个和前前一个才能直接登上这层楼,考虑的是哪一层是倒数第二层,而倒数第二层只能有一种方法登上这一层(并不是说经过前前一层只能有一种方法到达这一层,实际上并不是,而是以前前一层为倒数第二层这样直接到达当前层,考虑前一种的话,实际上是将dp[n-2]的一部分也算进去了,就重复了),故而其实和斐波那契数列很相似了。509. 斐波那契数。原创 2024-02-28 21:55:23 · 910 阅读 · 0 评论 -
代码随想录算法训练营day37|第八章 贪心算法 part06
可以看看贪心算法的总结,贪心本来就没啥规律,能写出个总结篇真的不容易了。代码随想录如果找出局部最优并可以推出全局最优,就是贪心,如果局部最优都没找出来,就不是贪心,可能是单纯的模拟。股票系列问题用贪心也可以解决,不只是动规的专长。在出现两个维度相互影响的情况时,两边一起考虑一定会顾此失彼,要先确定一个维度,再确定另一个一个维度。原创 2024-02-27 23:14:19 · 366 阅读 · 0 评论 -
代码随想录算法训练营day36|第八章 贪心算法 part05
文章中还介绍了另一种思路,并不是计数要删除的数量,而是计数区间不重合的数量,首先不是按照起始位置来排序,而是按照结束位置排序,遍历的时候,判断是否不大于这一个的起始位置,如是则计数并且更新前一个的结束位置,反之,就证明这个区间和上一个的有重合,而且因为已经事先排过序,所以必然这一个的结束位置要不小于上一个的结束位置,要保留区间长度尽可能小的区间,所以应该舍弃当前的区间,进而不用更新前一个的结束位置,下一个区间仍然还用这个位置判断。是大差不差的,稍微修改代码即可。435. 无重叠区间。435. 无重叠区间。原创 2024-02-25 21:35:20 · 393 阅读 · 0 评论 -
代码随想录算法训练营day34|第八章 贪心算法 part04
如果后一个起始下标大于前一个结束下标,那就肯定要多加一箭,反之,就肯定能在前一箭也能射中,不需要多加一箭,如果真的连射,就要更新这个气球的结束下标为当前结束下标和上一个气球结束下标中的较小者(其实本质上是一种值的传递,就是要传递这一箭最小区间的结束下标这个值用于判断下一个气球),来进一步判断是不是下一个气球也能在这一支箭的射程内。要先对人的数组进行排列,按照本身大小排列,如果本身大小相等,那就按照第二个值大小进行排序,这样就能保证前面的都是身高不小于本身的,所以第二个值就自然变成了要插入的下标号。原创 2024-02-21 23:11:32 · 359 阅读 · 0 评论 -
代码随想录算法训练营day33|第八章 贪心算法 part03
首先就是将一个问题分成几个小问题,这个题目是将走完整个数组的大问题分成能走到当前遍历到的下标处的小问题,具体也就是如果开始出发的下标处不能走到当前的下标处(也就是走到这汽油变成负数了),那就说明从当前下标以及之前的下标开始,都不能到达当前的下一个下标处,而如果一定存在一个开始处下标能走完整个数组(也就是加的汽油的总和不小于消耗的汽油的总和),那就一定是之后的下标作为开始处才可以实现。本题涉及到一个思想,就是想处理好一边再处理另一边,不要两边想着一起兼顾,后面还会有题目用到这个思路。原创 2024-02-21 17:19:42 · 921 阅读 · 0 评论 -
代码随想录算法训练营day 32|第八章 贪心算法 part02
还要注意一旦跳到最后一个点,就不需要往后跳了,所以最后一个点的射程多少不重要,i的范围保证在倒数第二个点(最后一个点之前的点都需要考虑射程范围来计算最远点),有可能最后一步的最大射程已经超过坐标范围了,但那不重要,重要的是何时更新这一步的最远点,之所以考虑倒数第二个点,是因为题目只道可达最后一点,但具体也有可能恰好是倒数第二个点到的最后一个点,那样就会更新这一步最远射程了,就算做一步了。贪心就是这样,有的时候 会感觉简单到离谱,有时候,难的不行,主要是不容易想到。122.买卖股票的最佳时机II。原创 2024-02-20 23:24:40 · 381 阅读 · 0 评论 -
代码随想录算法训练营day 31|第八章 贪心算法 part01
要注意摆动序列主要是出现前一个差值和后一个差值符号相反导致的,所以贪心的策略是贪每一处两个相邻差值符号相反的地方,所以关键就是要及时更新前一个差值和当前插差值,还有一个小细节是初始化result为1,因为差值变化出现的地方一定涉及两个数,需要有一个第一个数来作为开头,然后保证之后的每一个数 它与前一个数和后一个数的差值的符号相反即可,因为数组的第一个要判断的数必然是没有与前一个数的差值,所以允许起始的差值是0,但是当前的差值一定不能是0,这样就能保证只有第一个数的与前数差值是允许为0的,之后不可以。原创 2024-02-20 21:11:08 · 391 阅读 · 0 评论 -
代码随想录算法训练营day 30|第七章 回溯算法part06
首先要明确,这道题和上一道N皇后问题是不同的,主要在于N皇后是每一行找一个位置来试探,虽然也说是棋盘,但实际上对于一种解决方案并不是一行的每一个位置都要填入数据,这样只需要一行一行来解决问题即可(使用一层for循环),而解决数独问题是要在每一行的每一个空格内都填入数据,这是不能按照一行一行来解决问题的,而是要按照一个空格、一个空格来解决问题,所以就是二维的(需要两层for循环)。然后一个巧妙的方法找到所在九宫格的起始下标的方法是直接 /3,再*3,这样除去了余数,就直接是起始下标了。原创 2024-02-15 22:30:47 · 935 阅读 · 0 评论 -
代码随想录算法训练营day 29|第七章 回溯算法part05
如果必须保证nums序列的各个元素的相对顺序的话,没法自行让相等的值挨着,就要使用辅助数组法,也就是使用每个元素的值作为下标,来迅速查询这个值是否在当前for循环中被重复使用了.如果不必保证nums原本的顺序,那就直接sort排序nums,这样就能让相等的值必然相邻,保证当前遍历到的值不和上一个值相等即可,这样去重效率超高.原创 2024-02-09 18:22:39 · 1102 阅读 · 0 评论 -
代码随想录算法训练营day 28|第七章 回溯算法part04
至于怎么去重,节省空间的方法是直接将给出的nums排序,使得集合中相等的数均相邻,这样每次只要在for循环(每次for循环选择的数字的是当前位置的候选数字)中判断当前的数字是否和下标-1的数字是否相等(比较必须前提是当前下标>begin),若相等就跳过。这道题我和文章的思路一样的,都是没有另外开辟空间来存储路径,直接看作给一段数字插入三个点,保证每个区段的数字都合法,一旦满足已经插入了三个点,那就直接判断剩下的数字是否满足要求,满足要求的就储存到res数组中。整体代码其实和 回溯模板都是差不多的。原创 2024-02-06 18:29:26 · 473 阅读 · 0 评论 -
代码随想录算法训练营day 26|第七章 回溯算法part03
首先要明确重复数组是怎样产生的,重复是由于之前用过的数字再次出现在数组的同一位置,于是就要保证同一位置也就是同一个for循环中不能出现相同的数字(每一次for循环实际上就是为path数组的当前位置在合适区间中选择一个数)(也就是文章中提到的树层去重),因为之前已经为candidates排过序了,所以相同的数字必然下标相邻,这就大大方便树层去重。接着就是文章所指的树枝去重,意为下一层递归的数字要从当前下标之后的剩下的数字中选择,因为考虑的是下一步的情况,所以叫树枝去重。本题开始涉及到一个问题了:去重。原创 2024-02-05 22:49:55 · 834 阅读 · 0 评论 -
代码随想录算法训练营day 25|第七章 回溯算法part02
注意是直接传入参数digits字符串,这样只要同时传入要处理的下标,就可以一点一点处理整个字符串了。在每次for循环加入结果集合的时候要先判断这个要加入的值必然要不大于剩下的n,一旦i大于n,按照for循环i每次都++,后面i的值就都更不需要考虑了,所以直接return。1. 除了收获结果的时候要return,还要注意除了满足合法条件外一旦k或n小于等于0(我设置的是每次递归函数传入的参数都是减去push进去的值的),都要及return。如果把 组合问题理解了,本题就容易一些了。216.组合总和III。原创 2024-02-04 23:02:57 · 468 阅读 · 0 评论 -
代码随想录算法训练营day 24|第七章 回溯算法part01
对着 在 回溯算法理论基础 给出的 代码模板,来做本题组合问题,大家就会发现 写回溯算法套路在回溯算法解决实际问题的过程中,大家会有各种疑问,先看视频介绍,基本可以解决大家的疑惑本题关于剪枝操作是大家要理解的重点,因为后面很多回溯算法解决的题目,都是这个剪枝套路。,如果想让回溯法高效一些,可以加一些剪枝的操作,但也改不了回溯法就是穷举的本质。其实在讲解二叉树的时候,就给大家介绍过回溯,这次正式开启回溯算法,大家可以先看视频,对回溯算法有一个整体的了解。回溯是递归的副产品,只要有递归就会有回溯。原创 2024-02-04 18:50:17 · 433 阅读 · 0 评论 -
代码随想录算法训练营day 23|第六章 二叉树part09
递归的做法是将首先确定当前节点的值是否小于左边界,如果小于左边界,那么就给它的祖先节点返回当前节点的右孩子(注意不是直接返回右孩子,而是它的返回递归函数),同理如果它的值大于右边界,就返回当前节点的左孩子,如果恰好在边界内部,那就将它的左右孩子处理一下,处理成在边界内部的,然后返回当前节点——如果遇到某个节点的左孩子的值小于左边界,那就要一直执行将左孩子的右孩子赋值给当前节点的左孩子,直到使得当前节点满足要求为止,这样就能保证,当前节点以及它的右孩子一定是大于左边界的,这样再移动到当前节点的左孩子——原创 2024-02-04 00:09:04 · 839 阅读 · 1 评论 -
代码随想录算法训练营day 22|第六章 二叉树part08
这道题明晃晃就要是要利用二叉搜索树的节点大小的特点,如果当前节点的值比这两个的都要大,那就往左边找(单独左子树递归即可),如果当前的值比这两个的值都要小那就往右边找(单独右子树递归即可),如果恰好处于中间的一个值,那就证明当前节点就是最近公共祖先,然后返回给上个节点的递归即可(这么找上个节点必然是这个节点的父母节点,所以必然比这两个数都大或小),再直接返回找到的结果即可——首先要找到要删除的目标节点,然后再把删除节点之后的子树移接到它的父母节点,如果没有父母节点,就直接返回删除后的子树。原创 2024-02-03 15:59:32 · 979 阅读 · 1 评论 -
代码随想录算法训练营day 21|第六章 二叉树part07
对于二叉搜索树,那就和上一道题一个思路,也是在递归的时候处理中间节点,主要利用了中序遍历二叉搜索树是按照单调不减的顺序排列的,所以相等的两个数应该在中序遍历的结果中是相邻的,这时候可以根据是否和pre节点相等来统计出现的次数,而如果不相等那就直接重置统计的次数,开始新一轮的统计;这里的cmp函数就是直接正常的比较方法,但是在创建堆的时候是相反的比较,就是说大顶堆的判定函数是要左边小于右边,突然想到了,所以这里回忆一下怎么创建一个小顶堆,顺带复习一下map怎么遍历(是要使用iterator迭代器的)——原创 2024-02-03 01:07:02 · 922 阅读 · 1 评论 -
代码随想录算法训练营day 20|第六章 二叉树 part06
还有一种方法就是,在中序遍历的时候记录下每次的前一个节点,然后只是比较当前节点和上一个节点的大小,这一个上一个节点指的是它的中序遍历的上一个节点,每次在比较完当前节点之后,就需要更新上一个节点,那么当前节点root就被赋值给上一个节点pre,作为中序遍历的下一个节点的pre节点——但本题是有陷阱的,可以自己先做一做,然后在看题解,看看自己是不是掉陷阱里了。当然文章里面也提到了直接利用其中一个节点的方式,就是一旦两个节点都存在,就直接修改某一个节点的数值,不新建一个节点,而是利用老的节点。原创 2024-02-01 16:19:02 · 804 阅读 · 1 评论 -
代码随想录算法训练营day 18|第六章 二叉树 part05
主要的依据是后序遍历(左 右 根)和中序遍历(左 根 右)之间的联系,首先根据后序遍历能很容易确定每次根节点的数值(也就是数组的最后一个值),判断是否为叶子节点(遍历数组只有一个数值),如果叶子节点那就直接返回构造的根节点;接着根据这个值试图将中序遍历的数组分成左边部分和右边部分,然后再将后序遍历分成左边部分和右边部分(根据中序的左边部分的节点下标和后序左边部分的节点下标一一对应),来进一步实现递归。要回溯的过程,而且回溯的过程隐藏的还挺深,建议先看视频来理解。迭代法,使用层序遍历即可。原创 2024-01-29 23:59:37 · 396 阅读 · 0 评论 -
代码随想录算法训练营day 17第六章 二叉树part04
第一种递归方式,也是我选择的递归方式,就是将潜在的一条解决方案的路径按照vector<int>的方式存储(使用栈或者队列都并不方便,因为存入最后的结果数组的时候并不能将之前存入的数值pop掉,否则就会无法实现正确回溯),注意,数组传入的方式必须是传入地址,如果是复制的话,下层的递归改变的数组的值不会影响上层递归,导致回溯不成功——需要将根节点到每一个节点的路径都存储起来,然后试图更新这个路径(也就是增加路径的长度,到达它的子节点们),只有当该节点是叶子节点的时候才会真正存入结果数组中——原创 2024-01-29 00:20:23 · 317 阅读 · 0 评论 -
代码随想录算法训练营day 16|第六章 二叉树part03
不像求最大深度那样简单,因为要排除非叶子节点的子结点为NULL的干扰,如果不处理,就会导致一旦子结点出现NULL,就会直接认定该节点的最小深度是1,但这样是不符合深度的定义的,应该是到叶子节点的长度,而叶子节点的两个子节点都要是NULL才行,这样只保证了其中一个子节点是NULL,于是要判断如果只是一个子节点为NULL,那递归调用的时候,就只用返回所求不空的子节点的最小高度加一就行——但是,对于一棵二叉树来讲,根节点的最大高度就是这个二叉树的最大深度,所以可以通过后序遍历来求最大深度——原创 2024-01-28 12:28:19 · 375 阅读 · 0 评论 -
代码随想录算法训练营第十一天|递归遍历、迭代遍历、统一迭代
要先判断当前访问节点是否为空,如果不为空,就先压入栈中,试图访问它的左子节点,如果为空,就证明它的上一个节点(也就是当前栈顶元素)没有左子节点,那就可以直接退回到上个节点,并处理那个节点了,处理之后,就要试图访问它的右子节点,也就开启了新一轮循环,这时候,如果右子节点存在,那就压入栈中,再试图访问它的左子节点,若不存在,此时栈顶元素是当前访问节点的父节点的父节点,循环也依旧成立。其次通过改变在栈中存储该节点的左右子节点和自己本身的顺序,就可以保证遍历的顺序(提示一点:栈是先进后出,顺序要反过来)。原创 2024-01-25 18:30:18 · 772 阅读 · 0 评论 -
代码随想录算法训练营第十天|239. 滑动窗口最大值、347.前 K 个高频元素
239. 滑动窗口最大值 (一刷至少需要理解思路239. 滑动窗口最大值 (一刷至少需要理解思路之前讲的都是栈的应用,这次该是队列的应用了。本题算比较有难度的,需要自己去构造单调队列,建议先看视频来理解。这道题的整体思路是建立一个自己的特殊队列,要求这个队列保证单调不增。这样每次求最大值的时候直接取队列的front元素就行。原创 2024-01-23 23:49:50 · 867 阅读 · 1 评论