自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(49)
  • 收藏
  • 关注

原创 代码随想录算法训练营第62/63天| 503.下一个更大元素II、42. 接雨水、84.柱状图中最大的矩形

一旦发现添加的柱子高度大于栈头元素了,此时就出现凹槽了,栈头元素就是凹槽底部的柱子,栈头第二个元素就是凹槽左边的柱子,而添加的元素就是凹槽右边的柱子。stk.pop();后要记得判断if (!stk.empty()),因为有时候可能没有左边的柱子。遇到相同的元素,更新栈内下标,就是将栈里元素(旧下标)弹出,将新元素(新下标)加入栈中。和739. 每日温度 (opens new window)也几乎如出一辙,区别于。寻找右边第一个比自己大的元素,来计算雨水面积。

2024-03-02 15:36:48 493

原创 代码随想录算法训练营第60天|739. 每日温度 、496.下一个更大元素 I

更直白来说,就是用一个栈来记录我们遍历过的元素,因为我们遍历数组的时候,我们不知道之前都遍历了哪些元素,以至于遍历一个元素找不到是不是之前遍历过一个更小的,所以我们需要用一个容器(这里用单调栈)来记录我们遍历过的元素。遍历nums2[i],找到比nums2[i]大的右边第一个元素,然后判断nums2[i]是否在nums1中出现过,如果出现过开始记录元素。单调栈的本质是空间换时间,因为在遍历的过程中需要用一个栈来记录右边第一个比当前元素高的元素,优点是整个数组只需要遍历一次。

2024-03-01 14:38:35 474

原创 代码随想录算法训练营第59天|647. 回文子串、516.最长回文子序列

其他情况dp[i][j]初始为0就行,这样递推公式:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);如果s[i]与s[j]不相同,说明s[i]和s[j]的同时加入 并不能增加[i,j]区间回文子序列的长度,那么分别加入s[i]、s[j]看看哪一个可以组成最长的回文子序列。那么dp[i][j]一定是取最大的,即:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);加入s[j]的回文子序列长度为dp[i + 1][j]。

2024-02-29 23:23:38 840

原创 代码随想录算法训练营第57天|583. 两个字符串的删除操作、72. 编辑距离

那最后当然是取最小值,所以当word1[i - 1] 与 word2[j - 1]不相同的时候,递推公式:dp[i][j] = min({dp[i - 1][j - 1] + 2, dp[i - 1][j] + 1, dp[i][j - 1] + 1});2.if (word1[i - 1] == word2[j - 1]) 那么说明不用任何编辑,dp[i][j] 就应该是 dp[i - 1][j - 1],即dp[i][j] = dp[i - 1][j - 1];

2024-02-29 12:31:17 919

原创 代码随想录算法训练营第56天|392.判断子序列、115.不同的子序列

2.if (s[i - 1] == t[j - 1]),那么dp[i][j] = dp[i - 1][j - 1] + 1;= t[j - 1]),此时相当于t要删除元素,t如果把当前元素t[j - 1]删除,那么dp[i][j] 的数值就是 看s[i - 1]与 t[j - 2]的比较结果了,即:dp[i][j] = dp[i][j - 1];所以当s[i - 1] 与 t[j - 1]相等时,dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];

2024-02-28 22:49:49 740

原创 代码随想录算法训练营第56天|1143.最长公共子序列、1035.不相交的线、 53. 最大子序和

如果text1[i - 1] 与 text2[j - 1]不相同,那就看看text1[0, i - 2]与text2[0, j - 1]的最长公共子序列 和 text1[0, i - 1]与text2[0, j - 2]的最长公共子序列,取最大的。1.dp[i][j]:长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列为dp[i][j]即:dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);

2024-02-27 12:52:47 922

原创 代码随想录算法训练营第55天|300.最长递增子序列、674. 最长连续递增序列、 718. 最长重复子数组

设0<j<i,需要在nums[j]<nums[i]的dp[j]中找到最大值,+1即为dp[i],所以递推方程为:if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1)但dp[i][0] 和dp[0][j]要初始值,因为 为了方便递归公式dp[i][j] = dp[i - 1][j - 1] + 1;2.当A[i - 1] 和B[j - 1]相等的时候,dp[i][j] = dp[i - 1][j - 1] + 1。4.内外循环顺序都可。

2024-02-27 11:13:05 331

原创 代码随想录算法训练营第51天|309.最佳买卖股票时机含冷冻期、714.买卖股票的最佳时机含手续费

相对于动态规划:122.买卖股票的最佳时机II ,本题只需要在计算卖出操作的时候减去手续费就可以了,代码几乎是一样的。0:持有股票有三种情况①昨天就持有了②今天刚买入:前一天是冷冻期③今天刚买入:前一天保持卖出股票。1:保持卖出股票有两种情况①昨天就保持卖出股票②昨天是冷冻期。3:冷冻期:有一种情况①前一天卖出股票。2:卖出股票有一种情况①昨天持有股票。状态1:保持卖出股票。

2024-02-25 15:15:17 393

原创 代码随想录算法训练营第50天|123.买卖股票的最佳时机III、188.买卖股票的最佳时机IV

所以dp[4][4]已经包含了dp[4][2]的情况。选最大的,所以 dp[i][1] = max(dp[i - 1][0] - prices[i], dp[i - 1][1]);所以dp[i][2] = max(dp[i - 1][1] + prices[i], dp[i - 1][2])操作一:第i天买入股票了,那么dp[i][1] = dp[i - 1][0] - prices[i]操作一:第i天卖出股票了,那么dp[i][2] = dp[i - 1][1] + prices[i]

2024-02-24 11:57:15 923

原创 代码随想录算法训练营第49天|121. 买卖股票的最佳时机、122.买卖股票的最佳时机II

那么第i天持有股票即dp[i][0],如果是第i天买入股票,所得现金就是昨天不持有股票的所得现金 减去 今天的股票价格 即:dp[i - 1][1] - prices[i]要计算第i天所能获得的最大利润dp[i]有两种情况:①此时已经卖出了股票,即dp[i-1]②在第i天卖出股票,即prices[i] + 持有股票到第i-1天的最大利润。3.dp[0][0]表示第0天持有股票,此时的持有股票就一定是买入股票了,因为不可能有前一天推出来,所以dp[0][0] -= prices[0];

2024-02-23 20:43:55 410

原创 代码随想录算法训练营第46天|198.打家劫舍、213.打家劫舍II、337.打家劫舍III

如果不偷当前节点,那么左右孩子就可以偷,至于到底偷不偷一定是选一个最大的,val2 = max(left[0], left[1]) + max(right[0], right[1]);2.是否打劫第i个决定了dp[i]:如果打劫则dp[i] = dp[i - 2] + nums[i], 如果不打劫则dp[i] = dp[i - 1],取两者最大值。对于情况三,取nums[1] 和 nums[3]就是最大的。

2024-02-14 17:35:07 889

原创 代码随想录算法训练营第45天|139.单词拆分、多重背包、背包问题总结

代码随想录|背包问题总结。

2024-02-07 14:11:43 399

原创 代码随想录算法训练营第44天|70. 爬楼梯 (进阶)、322. 零钱兑换、279.完全平方数

2.凑足总额为j - coins[i]的最少个数为dp[j - coins[i]],那么只需要加上一个钱币coins[i]即dp[j - coins[i]] + 1就是dp[j],所以是在选和不选coins[i]两种情况取最小的:dp[i] = min(dp[i - coins[j]] + 1, dp[i])本题dp[i]有几种来源,dp[i - 1],dp[i - 2],dp[i - 3],即dp[i] += dp[i - j]3.dp[0] = 1,如果dp[0] = 0,其他数值都是0了。

2024-02-06 20:56:34 412

原创 代码随想录算法训练营第43天|完全背包 、518. 零钱兑换 II、377. 组合总和 Ⅳ

如果把遍历nums(物品)放在外循环,遍历target的作为内循环的话,举一个例子:计算dp[4]的时候,结果集只有 {1,3} 这样的集合,不会有{3,1}这样的集合,因为nums遍历放在外层,3只能出现在1后面!2.dp[i](考虑nums[j])可以由 dp[i - nums[j]](不考虑nums[j]) 推导出来。当coins[2]加入遍历时,d[j]表示包含coins[0]和coins[1]时的组合数 + 包含coins[2]时的组合数。

2024-02-03 16:05:36 879

原创 代码随想录算法训练营第42天|1049. 最后一块石头的重量 II 、494. 目标和 、474.一和零

1049. 最后一块石头的重量 II代码随想录|1049. 最后一块石头的重量 II。

2024-02-01 10:57:20 1011

原创 代码随想录算法训练营第42天|01背包问题(二维数组)、01背包问题(滚动数组)、416. 分割等和子集

其实从递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);在使用二维数组的时候,递推公式:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);所以递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);2. 可以由两个方向推出来dp[i][j]

2024-01-30 15:23:41 991

原创 代码随想录算法训练营第41天|343. 整数拆分、96.不同的二叉搜索树

所以dp[3] = dp[2] * dp[0] + dp[1] * dp[1] + dp[0] * dp[2]dp[3],就是 元素1为头结点搜索树的数量 + 元素2为头结点搜索树的数量 + 元素3为头结点搜索树的数量。元素1为头结点搜索树的数量 = 右子树有2个元素的搜索树数量 * 左子树有0个元素的搜索树数量。元素2为头结点搜索树的数量 = 右子树有1个元素的搜索树数量 * 左子树有1个元素的搜索树数量。元素3为头结点搜索树的数量 = 右子树有0个元素的搜索树数量 * 左子树有2个元素的搜索树数量。

2024-01-24 12:01:50 870

原创 代码随想录算法训练营第39天|62.不同路径、63. 不同路径 II

1.确定dp数组(dp table)以及下标的含义:dp[x][y]到达(x,y)存在的路径数量。相比于上一题,就多了个判断该点是否为障碍点,如果是障碍点就保持初始值0不变,不参与状态转移。2.确定递推公式:dp[x][y] = dp[x-1][y] + dp[x][y-1]3.dp数组如何初始化:dp[1][j] = 1;4.确定遍历顺序:x++;5.举例推导dp数组。

2024-01-18 16:41:19 431

原创 代码随想录算法训练营第38天|动态规划理论基础、509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯

2.到第i阶可以从第i-2阶跨两层上来,从第i-1阶跨一层上来,所以是第i-2的方法数量+第i-1的方法数量:dp[i] = dp[i - 1] + dp[i - 2]从递推公式dp[i] = dp[i - 1] + dp[i - 2]可以看出,dp[i] 是依赖前两项的,那么遍历顺序一定是从前到后遍历的。4.dp[i]由dp[i-1]dp[i-2]推出,所以是从前到后遍历cost数组。题目直接给了:dp[i] = dp[i - 1] + dp[i - 2]dp[i]定义为:第i个斐波那契数值是dp[i]

2024-01-17 14:09:18 431

原创 代码随想录算法训练营第37天|738.单调递增的数字、968.监控二叉树(待二刷)

当n=1000时,因为后面两位0是相等的,算法不会对其操作,只会从开头的1和0进行操作,返回的值为900,而正确答案应该是999。从后向前遍历,如果前一个数字比后一个数字大,就将前一个数字-1,然后将后一个数字赋值为9。所以要设置一个flag,记录离结尾最近的-1位置,然后把该位置后面全部设为9。

2024-01-16 22:36:53 351

原创 代码随想录算法训练营第36天|435. 无重叠区间、763.划分字母区间、56. 合并区间

求移除区间的最小数量,也就是求和别的区间重叠的区间,经过右边界排序后,设定第一个区间是非重叠区间,如果区间2和区间1重叠,就取区间2和区间1有边界的最小值end(也就是区间1的右边界),将end和区间3的左边界继续比较,如果重叠就继续更新end,不重叠就统计不重叠区间的数量count,最后intervals.size()-count即为重叠区间数量。其实就是用合并区间后左边界和右边界,作为一个新的区间,加入到result数组里,如果下一个还是重叠的,就更新result里最后一个左右边界。

2024-01-16 12:07:55 347

原创 代码随想录算法训练营第35天|860.柠檬水找零、406.根据身高重建队列、452. 用最少数量的箭引爆气球

这题可以先按身高h排序(身高相同k小的站前面),因为一定能排出一个队列结果,所以当前节点的位置一定是在k位置之后或者就在k位置。该节点前面的身高一定比当前高,所以可以按照节点中的信息k(前面有k个比该节点大或相等)重新插入队列的第k位置,也就是往前插。因为前面的节点比当前节点大,所以前面的节点即使被挤到后面去,前面节点的k仍然是成立的(k是指前面大于等于该节点h的数量)。重叠的区间射一只就能全部射到,所以题目也就是找重叠的区间和单独的区间一共有多少个。优先找10块的,因为5块的用处更大。

2024-01-16 00:06:26 348

原创 代码随想录算法训练营第33天|1005.K次取反后最大化的数组和、134. 加油站、135. 分发糖果

如果 ratings[i] > ratings[i + 1],此时candyVec[i](第i个小孩的糖果数量)就有两个选择了,一个是candyVec[i + 1] + 1(从右边这个加1得到的糖果数量),一个是candyVec[i](之前比较右孩子大于左孩子得到的糖果数量)。如果ratings[i] > ratings[i - 1] 那么[i]的糖 一定要比[i - 1]的糖多一个,所以贪心:candyVec[i] = candyVec[i - 1] + 1。再确定左孩子大于右孩子的情况(从后向前遍历)

2024-01-12 13:06:33 848

原创 代码随想录算法训练营第32天|122.买卖股票的最佳时机II、55. 跳跃游戏、45.跳跃游戏II

对于当前元素到其能跳到的最远元素curMaxPos,找到这些元素能跳到的最远元素nextMaxPos,如果遍历到curMaxPos时,nextMaxPos还没有到nums.size() - 1,说明还需要进行跳跃,继续往下遍历,否则终止遍历返回结果。关键在于可跳的最远位置,从当前位置遍历到最远位置,不断更新最远位置,如果超过了最后一个位置,就返回true。局部最优:收集每天的正利润,全局最优:求得最大利润。只要今天的利润是正的,就可以收集到最大利润中去。

2024-01-12 00:17:50 342

原创 代码随想录算法训练营第31天|贪心算法理论基础、455.分发饼干、376. 摆动序列、53. 最大子序和

针对以上情形,result 初始为 1(默认最右面有一个峰值),此时 curDiff > 0 && preDiff <= 0,那么 result++(计算了左面的峰值),最后得到的 result 就是 2(峰值个数为 2 即摆动序列长度为 2)注意,这里最后一个1也可能递增,此时不需要记录最后一个2这个峰值,只需要在 这个坡度 摆动变化的时候,更新 prediff 就行,这样 prediff 在 单调区间有平坡的时候 就不会发生变化,造成我们的误判。最好用的策略就是举反例,如果想不到反例,就试一试贪心。

2024-01-09 18:00:11 972

原创 代码随想录算法训练营第29天|491.递增子序列、46.全排列、47.全排列 II

与90.子集I不同,这题不能通过排序再加一个used数组来去重,因为本题是要求递增子序列,对原数组排序的话就全是自增子序列了。排列是数字序列的所有排列可能,返回是序列中的全部数字,所以每层需要从开头开始扫(不需要startIndex了),将没放入过的元素放入。和组合问题的去重套路一样,注意也要先排序这样才方便通过相邻节点判断是否重复使用。因为对于排列问题,树层上去重和树枝上去重,都是可以的,但是树层上去重效率更高。在本题中,如果改成 used[i - 1] == true, 也是正确的。

2024-01-04 15:25:15 322

原创 代码随想录算法训练营第28天|93.复原IP地址、78.子集、90.子集II

终止条件:剩余集合为空,也就是startIndex大于数组的长度(其实也可以不加终止条件,因为for循环中本来就是startIndex >= nums.size()停止的,每次递归的下一层就是从i+1开始的)递归结束条件:用pointSum记录加了几个点,加了三个后判断一下剩下的是否满足条件,满足就加入result。如果把 子集问题、组合问题、分割问题都抽象为一棵树的话,那么。左半部分满足条件,就添加’.',然后继续递归右半部分。40.组合总和II + 78.子集。和131.分割回文串类似。

2023-12-26 12:20:26 321

原创 代码随想录算法训练营第27天|39. 组合总和、40.组合总和II、131.分割回文串

为什么 used[i - 1] == false 就是同一树层呢,因为同一树层,used[i - 1] == false 才能表示,当前取的 candidates[i] 是从 candidates[i - 1] 回溯而来的。可以重复选择,就先对candidates进行排序,然后每次startIndex可以从当前元素开始,这样就可以出现2, 2, 3且不会出现2, 3, 2这样的结果。used[i - 1] == false,说明同一树层candidates[i - 1]使用过。对于字符串:abcbaa。

2023-12-24 11:32:10 901

原创 代码随想录算法训练营第25天|216.组合总和III、17.电话号码的字母组合

从1-9进行组合,增加判断求和。

2023-12-20 12:34:00 369

原创 代码随想录算法训练营第24天|回溯算法理论基础、77.组合

举个例子,n = 4,k = 3, 目前已经选取的元素为0(path.size为0),n - (k - 0) + 1 即 4 - ( 3 - 0) + 1 = 2。回溯算法解决的都是在集合中递归查找子集,集合的大小就构成了树的宽度,递归的深度,都构成的树的深度。如果for循环选择的起始位置之后的元素个数 已经不足 我们需要的元素个数了,那么就没有必要搜索了。每次从集合中选取元素,可选择的范围随着选择的进行而收缩,调整可选择的范围。也就是从1,2开始搜索都是合理的,可以是组合[2, 3, 4]。

2023-12-19 16:11:50 351

原创 代码随想录算法训练营第23天|669. 修剪二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树

如果结点的值小于 low那么说明该结点及它的左子树都不符合要求,我们返回对它的右结点进行修剪后的结果;如果结点的值大于high,那么说明该结点及它的右子树都不符合要求,我们返回对它的左子树进行修剪后的结果;修剪二叉搜索树 相较于 450.删除二叉搜索树中的节点来说,考虑的情况更少,因为只要该节点不在范围内,那么其左/右子树也就不在范围内。如果结点的值位于区间 [low,high],我们将结点的左结点设为对它的左子树修剪后的结果,右结点设为对它的右子树进行修剪后的结果。对根结点 root进行深度优先遍历。

2023-10-18 20:38:27 61 1

原创 代码随想录算法训练营第22天|235. 二叉搜索树的最近公共祖先、701.二叉搜索树中的插入操作、450.删除二叉搜索树中的节点

第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。如果从节点5继续向左遍历,那么将错过成为q的祖先, 如果从节点5继续向右遍历则错过成为p的祖先。第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点。第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点。第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点。

2023-10-10 12:53:43 137 1

原创 代码随想录算法训练营第21天|530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先

如果两个if判断顺序对调,maxCount = count;后count == maxCount成立,这样结果就往vec里push了两次。后序遍历整个二叉树,如果遇到p或q就往上返回,当一个节点接收到的两个子树的返回值都不为空时,就是最近公共祖先。如果这里的else if 是 if,那么当pre==NULL时这行也会运行,pre->val会报错空指针。能else if 就 else if ,不要只写个if偷懒!如果不是空节点且有儿子节点,则写在层处理中。如果是空节点或叶子结点,则跟终止条件有关。

2023-10-07 21:04:54 56 1

原创 代码随想录算法训练营第20天|654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树

构造函数的时候,第二个参数的迭代器指向的是目标元素的后一个,nums.end()指向的也是最后一个元素的后一个停止标志,简单来说就是左闭右开:[nums.begin(), nums.begin() + maxValueIndex)寻找一个不符合条件的节点,如果没有找到这个节点就遍历了整个树,如果找到不符合的节点了,立刻返回。构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。注意运用二叉树搜索树的特性:左子节点小于根节点,右子节点大于根节点。中序遍历下,输出的二叉搜索树的数值是。

2023-09-26 11:33:28 69

原创 代码随想录算法训练营第18天|513.找树左下角的值、112. 路径总和113.路径总和ii、106.从中序与后序遍历序列构造二叉树105.从前序与中序遍历序列构造二叉树

遍历每个节点,比较每个叶子节点的深度,找到深度最大的叶子节点。又因为不管是什么顺序的遍历,左节点都比右节点先遍历到,所以记录下最深的第一个节点值即可。就是遍历整棵树,且不需要处理递归返回值。因此我们可以先通过后序遍历找到某个子树的根节点,然后用这个根节点在中序遍历中区分该子树的两个子树,然后递归找这两个子树的子树……输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]层序遍历,用队列实现,记录每一层的第一个元素,最后存着的就是最后一层的最左边元素。

2023-09-22 21:02:54 303

原创 代码随想录算法训练营第17天|110.平衡二叉树、257. 二叉树的所有路径、404.左叶子之和

运用求高度的后序遍历递归法,在每一次递归求得的左右子树高度后,加一个判断,如果高度差超过1则返回-1,并直接在每次递归时一个一个传到根节点。,每个父节点获得左节点的左叶子和+右节点的左叶子和,如果左子节点就是左叶子则父节点获得左子节点值+右节点的左叶子和。在写递归函数时,首先要想好是用的什么遍历方式,写的过程中要时刻清楚cur是指的哪个节点(父节点or子节点)本题需要输出每一条路径,创建一个vector存放遍历的节点,并在vector中模仿递归本来就存在的回溯。因为是从根节点出发,所以用前序遍历(中左右)

2023-08-31 23:35:13 39

原创 代码随想录算法训练营第16天|104.二叉树的最大深度、111.二叉树的最小深度、 222.完全二叉树的节点个数

我们从这个子树的根节点出发,一直左走计算深度,再一直往右走计算深度,如果两边的深度相等,那么根据完全二叉树的性质,则可以判定此二叉树为满二叉树。每个节点的最大深度都是其子节点的最大深度+1,因此可以用递归的思想,终止条件是遇到叶子结点返回0(叶子结点的深度为0)。但需要注意的是,如果一个节点的子节点一个为空另一个非空,其最小深度则会判定为0,这是错误的(而它并不是叶子结点),所以要做额外的判断。跟上一题类似,每个节点的最小深度都是其子节点的最小深度+1,因此可以用递归的方法进行后序遍历。

2023-08-31 01:28:07 189

原创 代码随想录算法训练营第15天|二叉树层序遍历、226.翻转二叉树、101. 对称二叉树

当弹出一层的节点,也就放入了下一层所有的节点,这个时候记录下队列的长度size(控制后面弹出的节点数量),也就是该层的所有节点的数量。其实是比较根节点的左右子树是不是互相翻转的,在递归遍历的过程也要同时遍历两棵树,比较两个子树的内侧和外侧元素是否相等。中序遍历:先反转左子树,再交换左右孩子节点,再反转右子树,相当于是只反转了两次左子树。对于层序遍历来说,就是每弹出一个节点时,放入队列其左右子节点。前序遍历:先交换左右孩子节点,再反转左子树,反转右子树。后序遍历:先反转左子树,右子树,再交换左右孩子节点。

2023-08-28 19:02:20 1318 1

原创 代码随想录算法训练营第14天|二叉树的理论基础、递归遍历、迭代遍历、统一迭代

int val;

2023-08-27 15:39:06 1565 1

原创 代码随想录算法训练营第13天|239. 滑动窗口最大值、347.前 K 个高频元素

构建一个单调递减队列,放进窗口里的元素,然后随着窗口的移动,队列也一进一出,每次移动之后,队列告诉我们里面的最大值是什么。所以大家经常说的大顶堆(堆头是最大元素),小顶堆(堆头是最小元素),如果懒得自己实现的话,就直接用priority_queue(优先级队列)就可以了,底层实现都是一样的,从小到大排就是小顶堆,从大到小排就是大顶堆。push(value):如果push的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到push元素的数值小于等于队列入口元素的数值为止。

2023-08-24 20:42:48 1299 1

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除