自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 单调栈part3 | 84.柱状图中最大的矩形

第一遍完结!!后续贪心,动态规划和单调栈需要加强!!!也要掌握常用的手撕比如树的遍历。

2023-07-10 21:03:14 311

原创 单调栈part2 | ● 503.下一个更大元素II ● 42. 接雨水

此时的栈顶元素st.top(),就是凹槽的左边位置,下标为st.top(),对应的高度为height[st.top()](就是图中的高度2)。取栈顶元素,将栈顶元素弹出,这个就是凹槽的底部,也就是中间位置,下标记为mid,对应的高度为height[mid](就是图中的高度1)。当前遍历的元素i,就是凹槽右边的位置,下标为i,对应的高度为height[i](就是图中的高度3)。resize倒是不费时间,是O(1)的操作,但扩充nums数组相当于多了一个O(n)的操作。当前凹槽雨水的体积就是:h * w。

2023-07-09 21:24:51 263

原创 单调栈part1 | ● 739. 每日温度 ● 496.下一个更大元素 I

更直白来说,就是用一个栈来记录我们遍历过的元素,因为我们遍历数组的时候,我们不知道之前都遍历了哪些元素,以至于遍历一个元素找不到是不是之前遍历过一个更小的,所以我们需要用一个容器(这里用单调栈)来记录我们遍历过的元素。通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时我们就要想到可以用单调栈了。时间复杂度为O(n)。单调栈的本质是空间换时间,因为在遍历的过程中需要用一个栈来记录右边第一个比当前元素高的元素,优点是整个数组只需要遍历一次。时间复杂度为O(n)。

2023-07-09 17:52:13 224

原创 动态规划part17 | ● 647. 回文子串 ● 516.最长回文子序列

情况三:下标:i 与 j相差大于1的时候,例如cabac,此时s[i]与s[j]已经相同了,我们看i到j区间是不是回文子串就看aba是不是回文就可以了,那么aba的区间就是 i+1 与 j-1区间,这个区间是不是回文就看dp[i + 1][j - 1]是否为true。当s[i]与s[j]不相等,那没啥好说的了,dp[i][j]一定是false。整体上是两种,就是s[i]与s[j]相等,s[i]与s[j]不相等这两种。当s[i]与s[j]相等时,这就复杂一些了,有如下三种情况。

2023-07-09 15:39:31 220

原创 动态规划part16 | ● 583. 两个字符串的删除操作 ● 72. 编辑距离

word2[j - 1]) 时取最小的,即:dp[i][j] = min({dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]}) + 1;可以回顾一下,if (word1[i - 1] == word2[j - 1])的时候我们的操作 是 dp[i][j] = dp[i - 1][j - 1] 对吧。所以 dp[i][j] = dp[i - 1][j - 1] + 1;即 dp[i][j] = dp[i - 1][j] + 1;编辑对应的增删改操作。

2023-07-04 17:02:25 216

原创 动态规划part15 | ● 392.判断子序列 ● 115.不同的子序列

dp[i][j]:以i-1为结尾的s子序列中出现以j-1为结尾的t的个数为dp[i][j]。非连续子序列问题 使用s[i-1]==t[j-1]来判断。确定dp数组(dp table)以及下标的含义。

2023-07-04 15:57:34 99

原创 动态规划part14 | ● 1143.最长公共子序列 ● 1035.不相交的线 ● 53. 最大子序和

dp[i][j]:长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列为dp[i][j]如果是连续的组序列,那么一般是dp代表前i个数,包含nums[i]。dp代表前i个数,包含nums[i]的值最大子序和。问题转换成最长公共子序列问题,保证顺序就不会香交。就是求最长公共子序列。

2023-07-01 13:47:21 159

原创 动态规划part13 | ● 300.最长递增子序列 ● 674. 最长连续递增序列 ● 718. 最长重复子数组

dp[i][j] :以下标i - 1为结尾的A,和以下标j - 1为结尾的B,最长重复子数组长度为dp[i][j]。dp数组的定义 dp[i]表示取第i个元素的时候,表示子序列的长度,其中包括 nums[i] 这个元素。dp数组的定义 dp[i]表示取第i个元素的时候,表示子序列的长度,其中包括 nums[i] 这个元素。dp含义变成dp[i]表示取第i个元素的时候,表示子序列的长度,其中包括 nums[i] 这个元素。初始化,所有的元素都应该初始化为1。

2023-06-30 17:10:59 165

原创 动态规划part12 | ● 309.最佳买卖股票时机含冷冻期 ● 714.买卖股票的最佳时机含手续费

状态二:保持卖出股票的状态(两天前就卖出了股票,度过一天冷冻期。或者是前一天就是卖出股票状态,一直没操作)状态一:持有股票状态(今天买入股票,或者是之前就买入了股票然后没有操作,一直持有)状态四:今天为冷冻期状态,但冷冻期状态不可持续,只有一天!一共三个状态 持有股票 未持有股票 冷冻期。不持有股票状态,这里就有两种卖出股票状态。dp代表当天每个状态对应的最大值。卖出股票的时候扣除手续费即可。持有股票只能从冷冻期购买。股票问题对于状态的设计。状态三:今天卖出股票。

2023-06-29 10:38:20 73

原创 动态规划part11 | ● 123.买卖股票的最佳时机III ● 188.买卖股票的最佳时机IV

例如 dp[i][1] ,并不是说 第i天一定买入股票,有可能 第 i-1天 就买入了,那么 dp[i][1] 延续买入股票的这个状态。需要注意:dp[i][1],表示的是第i天,买入股票的状态,并不是说一定要第i天买入股票,这是很多同学容易陷入的误区。dp[i][j]中 i表示第i天,j为 [0 - 4] 五个状态,dp[i][j]表示第i天状态j所剩最大现金。股票问题允许交易k次,此时可以设多个状态(2k个),代表第几次交易的持有股票和不持有股票。和上题一样,只不过状态更多罢了。一天一共就有五个状态,

2023-06-28 11:33:24 131

原创 动态规划part10 | ● 121. 买卖股票的最佳时机 ● 122.买卖股票的最佳时机II

在121. 买卖股票的最佳时机 (opens new window)中,因为股票全程只能买卖一次,所以如果买入股票,那么第i天持有股票即dp[i][0]一定就是 -prices[i]。那么第i天持有股票即dp[i][0],如果是第i天买入股票,所得现金就是昨天不持有股票的所得现金 减去 今天的股票价格 即:dp[i - 1][1] - prices[i]。第i-1天就持有股票,那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1][0]dp[1]代表不持有股票。dp[0]代表持有股票。

2023-06-27 13:09:37 72

原创 动态规划part9 | ● 198.打家劫舍 ● 213.打家劫舍II ● 337.打家劫舍III

如果偷第i房间,那么dp[i] = dp[i - 2] + nums[i] ,即:第i-1房一定是不考虑的,找出 下标i-2(包括i-2)以内的房屋,最多可以偷窃的金额为dp[i-2] 加上第i房间偷到的钱。如果不偷第i房间,那么dp[i] = dp[i - 1],即考 虑i-1房,(注意这里是考虑,并不是一定要偷i-1房,这是很多同学容易混淆的点)然后dp[i]取最大值,即dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);dp含义,偷前i个房,切第i个房偷。

2023-06-26 13:00:36 173

原创 动态规划part8 | 139.单词拆分

使用memory数组保存每次计算的以startIndex起始的计算结果,如果memory[startIndex]里已经被赋值了,直接用memory[startIndex]的结果。递归的过程中有很多重复计算,可以使用数组保存一下递归过程中计算的结果。如果和排列有关,即排列不同结果不同,这就是排列问题,要外层遍历背包。这个叫做记忆化递归,这种方法我们之前已经提过很多次了。不同排列有不同结果,所以这是排列问题,要外层遍历背包。

2023-06-25 17:08:58 46

原创 动态规划part7 | ● 322. 零钱兑换 ● 279.完全平方数

dp初始化的时候要置为最大值,这样才能判断是否能装入。和上题一致,注意自己转换物品。完全背包最少个数问题。

2023-06-24 11:19:57 78

原创 动态规划part6 | ● 518. 零钱兑换 II ● 377. 组合总和 Ⅳ

如果把遍历nums(物品)放在外循环,遍历target的作为内循环的话,举一个例子:计算dp[4]的时候,结果集只有 {1,3} 这样的集合,不会有{3,1}这样的集合,因为nums遍历放在外层,3只能出现在1后面!所以本题遍历顺序最终遍历顺序:target(背包)放在外循环,将nums(物品)放在内循环,内循环从前到后遍历。完全背包问题,相比0-1背包,内层循环遍历方式为正向遍历即可。如果求组合数就是外层for循环遍历物品,内层for遍历背包。如果求排列数就是外层for遍历背包,内层for循环遍历物品。

2023-06-23 15:01:26 386

原创 动态规划part5 | ● 1049. 最后一块石头的重量 II ● 494. 目标和 ● 474.一和零

1049.最后一块石头的重量 II。

2023-06-21 11:02:39 212

原创 动态规划part4 | ● 416. 分割等和子集

同时能对2维dp优化,滚动数组模拟上一层dp,因为只需要上一层dp,为了不影响上一层dp的状态,即不将物品重复放入背包,因为是从左上方取值的,所以应该倒叙遍历。即一个商品如果可以重复多次放入是完全背包,而只能放入一次是01背包,写法还是不一样的。问题转换成容量为总数除以2的背包能不能放满,两种情况,当前的物品放了和当前的没放。背包要放入的商品(集合里的元素)重量为 元素的数值,价值也为元素的数值。0-1背包问题,思路是判断当前物品放不放入背包中,即0-1的状态。背包的体积为sum / 2。

2023-06-20 13:33:32 137

原创 动态规划part3 | 343. 整数拆分 ● 96.不同的二叉搜索树

(可能有同学问了,这布局不一样啊,节点数值都不一样。别忘了我们就是求不同树的数量,并不用把搜索树都列出来,所以不用关心其具体数值的差异)当1为头结点的时候,其右子树有两个节点,看这两个节点的布局,是不是和 n 为2的时候两棵树的布局是一样的啊!当3为头结点的时候,其左子树有两个节点,看这两个节点的布局,是不是和n为2的时候两棵树的布局也是一样的啊!当2为头结点的时候,其左右子树都只有一个节点,布局是不是和n为1的时候只有一棵树的布局也是一样的啊!动态规划的思想,根据前一个数的结果判断当前数。

2023-06-19 21:28:16 94

原创 动态规划part2 | 62.不同路径 ● 63. 不同路径 II

if (obstacleGrid[i][j] == 0) { // 当(i, j)没有障碍的时候,再推导dp[i][j]和上一样,区别只在于遇到障碍物将dp对应位置置为-1,以后计算路径的时候跳过-1即可,注意如果结果是-1,要变成0.递推公式和62.不同路径一样,dp[i][j] = dp[i - 1][j] + dp[i][j - 1]。这时初始化的时候就要使dp[1][1]=1,可以让它上方的为1,这样遍历过程中就自动变位1了。给数组扩容一行一列,方便处理边界条件。从左至右,从上至下遍历。

2023-06-17 09:34:49 548

原创 动态规划part1 | ● 509. 斐波那契数 ● 70. 爬楼梯 ● 746. 使用最小花费爬楼梯

dp数组保存前两个数和前一个数,通过dp[0]+dp[1]计算当前数,然后更新dp数组。从前一阶和前二阶往上爬1步的方法数相加等于爬上当前阶的方法数。可以从第0和第1开始,思考清楚dp数组含义,,然后再根据递推公式循环。

2023-06-16 11:42:09 52

原创 贪心算法part6 | ● 738.单调递增的数字 ● 968.监控二叉树

代码随想录算法训练营第一天 | 题目、题目。

2023-06-15 09:11:45 1619

原创 贪心算法part5 | ● 435. 无重叠区间 ● 763.划分字母区间 ● 56. 合并区间

统计字符串中所有字符的起始和结束位置,记录这些区间(实际上也就是435.无重叠区间 (opens new window)题目里的输入),将区间按左边界从小到大排序,找到边界将区间划分成组,互不重叠。在遍历的过程中相当于是要找每一个字母的边界,如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了。从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点。要找出最少删除的数量,也就是找出重叠空间的数量,然后用长度减去即可。搞清楚左右区间,重叠的条件。

2023-06-14 12:08:04 1186

原创 贪心算法part4 | ● 860.柠檬水找零 ● 406.根据身高重建队列 ● 452. 用最少数量的箭引爆气球

文章目录860.柠檬水找零思路思路代码406.根据身高重建队列思路思路代码官方题解代码困难题目思路思路代码官方题解代码困难今日收获本题有两个维度,h和k,看到这种题目一定要想如何确定一个维度,然后再按照另一个维度重新排列。860.柠檬水找零860.柠檬水找零思路所以局部最优:遇到账单20,优先消耗美元10,完成本次找零。全局最优:完成全部账单的找零。思路代码func lemonadeChange(bills []int) bool { cash:=[2]int{} for _,

2023-06-13 10:40:53 1650

原创 贪心算法part3 | ● 1005.K次取反后最大化的数组和 ● 134. 加油站 ● 135. 分发糖果

如果 ratings[i] > ratings[i + 1],此时candyVec[i](第i个小孩的糖果数量)就有两个选择了,一个是candyVec[i + 1] + 1(从右边这个加1得到的糖果数量),一个是candyVec[i](之前比较右孩子大于左孩子得到的糖果数量)。i从0开始累加rest[i],和记为curSum,一旦curSum小于零,说明[0, i]区间都不能作为起始位置,因为这个区间选择任何一个位置作为起点,到i这里都会断油,那么起始位置从i+1算起,再从0计算curSum。

2023-06-12 11:58:14 520

原创 贪心算法part2 | ● 122.买卖股票的最佳时机II ● 55. 跳跃游戏 ● 45.跳跃游戏II

让i每次只能在cover内移动,每次循环实时更新cover的值,也就是循环的范围在循环的同时就可以扩大,不需要两层循环。贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点。每次移动取最大跳跃步数(得到最大的覆盖范围),每移动一个单位,就更新最大覆盖范围。例如跳跃问题这种每次更新范围的问题,使用一个循环,贪心找到每一步覆盖的最大范围。局部最优:将当天价格和前一天比较,价格涨了就买入,价格降了就忽略。对贪心算法的局部最优有了更深的认识。

2023-06-10 11:17:01 1397

原创 贪心算法part1 | ● 455.分发饼干 ● 376. 摆动序列 ● 53. 最大子序和

在计算是否有峰值的时候,大家知道遍历的下标 i ,计算 prediff(nums[i] - nums[i-1]) 和 curdiff(nums[i+1] - nums[i]),如果prediff < 0 && curdiff > 0 或者 prediff > 0 && curdiff < 0 此时就有波动就需要统计。实际操作上,其实连删除的操作都不用做,因为题目要求的是最长摆动子序列的长度,所以只需要统计数组的峰值数量就可以了(相当于是删除单一坡度上的节点,然后统计长度)如何才能得到最大“连续和”呢?

2023-06-09 14:59:24 1089

原创 回溯算法part6(高阶!) | ● 332.重新安排行程 ● 51. N皇后 ● 37. 解数独

递归根据传入的出发点,得到到达点数组,从中选取新的出发点,如果新的出发点能够到达,那么就return true,负责继续迭代选取。那么使用map记录每个出发点和到达点集合的映射,并且已经使用的票不能再次使用,所以还要记录到达点结合中是否已经有到达过的,自定义pair结构体,维护visited字段。递归终止条件是路径上的节点数目等于票的数目+1,很容易理解,一张票能到达两个地方,两张票三个地方。由于只需要找到一次符合条件的路径就是答案,不需要遍历所有路径,所以递归需要返回值bool。

2023-06-08 14:00:06 410

原创 回溯算法part5 | * 491.递增子序列 * 46.全排列 * 47.全排列 II

同样有去重和树节点需求,但与之前的排列不同的是,这次子序列要和原题一致,所以不能采用排序和used数组的方式。used数组中的数i如果为true代表在递归过程中使用过,如果i-1为false代表在同树层遍历过程中使用过。used数组中的数i如果为true代表在递归过程中使用过,如果i-1为false代表在同树层遍历过程中使用过。不同于组合问题,不需要startindex,但是需要记录已经选择的数,递归的时候从剩下的未选择的数中选。需要去重,和之前组合去重思路相同,used数组去重同树层数。

2023-06-07 13:25:01 438

原创 回溯算法part4 | ● 93.复原IP地址 ● 78.子集 ● 90.子集II

path记录分割的位置,每次判断分割能否成功,只有到分割到了len(s)的位置并且这时len(path)==4,才能终止回溯。和之前的组合问题去重一样,去的是同一树层的重,先对nums排序,然后used数组记录同一树层的是否被使用过。求排列问题的时候,就要从0开始,因为集合是有序的,{1, 2} 和{2, 1}是两个集合,排列问题我们后续的文章就会讲到的。其实子集也是一种组合问题,因为它的集合是无序的,子集{1,2} 和 子集{2,1}是一样的。

2023-06-06 11:33:23 285

原创 回溯算法part3 | ● 39. 组合总和 ● 40.组合总和II ● 131.分割回文串

都知道组合问题可以抽象为树形结构,那么“使用过”在这个树形结构上是有两个维度的,一个维度是同一树枝上使用过,一个维度是同一树层上使用过。2.startindex表示开始切割的位置,i表示第二次切割的位置,语义虽然有很大变化,但代码改动不大,仅仅是for循环i的加1还是不加的区别。递归用来纵向遍历,for循环用来横向遍历,切割线(就是图中的红线)切割到字符串的结尾位置,说明找到了一个切割方法。前面我们提到:要去重的是“同一树层上的使用过”,如何判断同一树层上元素(相同的元素)是否使用过了呢。

2023-06-05 11:49:07 232

原创 回溯算法part2 | ● 216.组合总和III ● 17.电话号码的字母组合

其实这里sum这个参数也可以省略,每次targetSum减去选取的元素数值,然后判断如果targetSum为0了,说明收集到符合条件的结果了,我这里为了直观便于理解,还是加一个sum参数。如果此时path里收集到的元素和(sum) 和targetSum(就是题目描述的n)相同了,就用result收集当前的结果。处理过程就是 path收集每次选取的元素,相当于树型结构里的边,sum来统计path里元素的总和。至于为什么取名为path?sum(int)为已经收集的元素的总和,也就是path里元素的总和。

2023-06-03 13:52:34 162

原创 回溯算法part1 | 77. 组合

代码随想录算法训练营第一天 | 题目、题目。

2023-06-02 13:45:02 274

原创 二叉树part9 | ● 669. 修剪二叉搜索树 ● 108.将有序数组转换为二叉搜索树 ● 538.把二叉搜索树转换为累加树

其实这就是一棵树,大家可能看起来有点别扭,换一个角度来看,这就是一个有序数组[2, 5, 13],求从后到前的累加数组,也就是[20, 18, 13],是不是感觉这就简单了。那么知道如何遍历这个二叉树,也就迎刃而解了,从树中可以看出累加的顺序是右中左,所以我们需要反中序遍历这个二叉树,然后顺序累加就可以了。如果root(当前节点)的元素小于low的数值,那么应该递归右子树,并返回右子树符合条件的头结点。如果root(当前节点)的元素大于high的,那么应该递归左子树,并返回左子树符合条件的头结点。

2023-06-01 13:42:03 343

原创 二叉树part8 | ● 235. 二叉搜索树的最近公共祖先 ● 701.二叉搜索树中的插入操作 ● 450.删除二叉搜索树中的节点

不同于236普通二叉树,由于是二叉搜索树,只需要第一个遍历到小于q大于p的节点即可。第三种情况:删除节点的左孩子为空,右孩子不为空,删除节点,右孩子补位,返回右孩子为根节点。第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点。第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点。由于怎么插入都可以,不考虑改变二叉树结构的插入方法,直接插入空节点。第一种情况:没找到删除的节点,遍历到空节点直接返回了。着重考虑删除节点的第五种情况。

2023-05-31 13:14:46 293

原创 二叉树part7 | ● 530.二叉搜索树的最小绝对差 ● 501.二叉搜索树中的众数 ● 236. 二叉树的最近公共祖先

在递归函数有返回值的情况下:如果要搜索一条边,递归函数返回值不为空的时候,立刻返回,如果搜索整个树,直接用一个变量left、right接住返回值,这个left、right后序还有逻辑处理的需要,也就是后序遍历中处理中间节点的逻辑(也是回溯)。首先最容易想到的一个情况:如果找到一个节点,发现左子树出现结点p,右子树出现节点q,或者 左子树出现结点q,右子树出现节点p,那么该节点就是节点p和q的最近公共祖先。遇到在二叉搜索树上求什么最值啊,差值之类的,就把它想成在一个有序数组上求最值,求差值,这样就简单多了。

2023-05-30 15:37:04 493

原创 二叉树part6 | ● 654.最大二叉树 ● 617.合并二叉树 ● 700.二叉搜索树中的搜索 ● 98.验证二叉搜索树

目的是合并ab树,每一步递归要做的事当前节点的值为a树和b树相加,左子树为a树左子树和b树左子树递归合并,右子树为a树右子树和b树右子树递归合并。递归,每一层递归的目的是判断当前节点的左右子树的所有节点是否都小于或大于当前节点,然后再递归地判断左右子树是否是二叉搜索树。开始递归的条件和者终止条件要保持一致性,比如默认只有节点不为空才开始递归,那么终止条件就可以不写节点为空。有了这个特性,验证二叉搜索树,就相当于变成了判断一个序列是不是递增的了。要知道中序遍历下,输出的二叉搜索树节点的数值是有序序列。

2023-05-29 16:34:51 586

原创 二叉树part5 | ● 513.找树左下角的值 ● 112. 路径总和 113.路径总和ii ● 106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树

后序遍历对应子树在中序遍历数组的位置是会不断发生偏移的,每判断一次右子树,中序遍历就会往右偏移一位,所以要统计右子树的判断次数,同时将对应位置减去偏移的位数。前序遍历对应子树在中序遍历数组的位置是会不断发生偏移的,每判断一次左子树,中序遍历就会往左偏移一位,所以要统计左子树的判断次数,同时将对应位置加上偏移的位数。所以可以根据后序遍历的末尾在中序遍历数组中找到对应位置,从而在后序遍历数组中区分左右子树。所以可以根据前序遍历的开头在中序遍历数组中找到对应位置,从而在前序遍历数组中区分左右子树。

2023-05-28 16:59:20 47

原创 二叉树part4 | 110.平衡二叉树 ● 257. 二叉树的所有路径 ● 404.左叶子之和

可以使用前序遍历最先遍历到左叶子节点,如果一直left走到nil并且能够从left走,同时是叶子节点,那么这个节点一定是左叶子节点。平时我们解二叉树的题目时,已经习惯了通过节点的左右孩子判断本节点的属性,而本题我们要通过节点的父节点判断本节点的属性。分别求出其左右子树的高度,然后如果差值小于等于1,则返回当前二叉树的高度,否则返回-1,表示已经不是二叉平衡树了。判断当前节点是不是左叶子是无法判断的,必须要通过节点的父节点来判断其左孩子是不是左叶子。返回值:以当前传入节点为根节点的树的高度。

2023-05-26 17:30:24 61

原创 二叉树part3 | ● 104.二叉树的最大深度 559.n叉树的最大深度 ● 111.二叉树的最小深度 ● 222.完全二叉树的节点个数

注意只要求到叶子节点,所以递归的时候判断如果子树为nil,就不进行递归。在判断外部记录结果(足够大的值),进到递归后更新这个值。最后如果都不进行递归说明没有左右子树,这时候才可以判断其子树的最小深度为0。递归根据这个条件,先判断左右子节点是否是完全二叉树,是的话用公式计算2^h-1。: 将左右节点的最大深度相比取最大值然后加1,也就是当前节点的最大深度。: 根节点为nIl,直接返回0,深度为0。对二叉树问题结合递归解法有了更深的了解。根据完全二叉树的条件写递归终止的逻辑。时间复杂度Ologn*Ologn。

2023-05-25 16:28:02 37

原创 二叉树part2 | ● 层序遍历 10 ● 226.翻转二叉树 ● 101.对称二叉

递归法,先翻转左子树,再翻转右子树,最后将反转后的左右子树赋给右节点和左节点。对二叉树的遍历方式和递归回溯的结合有了更深的了解。后序遍历,同时遍历两颗二叉树。

2023-05-24 17:02:16 49

空空如也

空空如也

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

TA关注的人

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