自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 代码随想录训练营第60天| ● 84.柱状图中最大的矩形

与上题类似,只是改为递减的单调栈。84.柱状图中最大的矩形。

2024-01-07 14:38:21 510 1

原创 代码随想录训练营第五十九天| ● 503.下一个更大元素II ● 42. 接雨水

这道题使用单调栈的方法,在遍历到的元素大于栈顶元素时,说明中间出现了低地,如果栈左边还有元素,说明该地左右都大于它,因此可以用来装雨水。这道题是循环数组,因此在遍历时要遍历nums.size()*2次,然后再读取nums中的元素时要使用i % nums.size()来得到对应的下标。建议是掌握 双指针 和单调栈,因为在面试中 写出单调栈可能 有点难度,但双指针思路更直接一些。接雨水这道题目是 面试中特别高频的一道题,也是单调栈 应用的题目,大家好好做做。503.下一个更大元素II。

2024-01-07 10:00:22 622

原创 代码随想录训练营第五十八天| (单调栈)● 739. 每日温度 ● 496.下一个更大元素 I

在栈中是递增来存储元素的,从栈顶到栈底的元素大小是递增排序的。每遍历到一个元素就要将元素存入栈中,当存入栈的元素大于当前栈顶的元素,就要将栈顶元素弹出,并计算温度天数的差值,重复执行直至当前元素小于栈顶元素。这道题比上道题复杂了一点,有两个数组,nums1是nums2的子集,所以需要一个map来对nums1的元素进行映射,将nums1中的元素和下标存入map中,在nums遍历的过程中判断该元素在nums1中是否存在,同时要根据map的key和value来找到nums2中的元素再nums1中的下标。

2024-01-06 09:55:00 544

原创 代码随想录训练营第五十七天| ● 647. 回文子串 ● 516.最长回文子序列● 动态规划总结篇

初始化方面:首先要考虑当i 和j 相同的情况,从递推公式:dp[i][j] = dp[i + 1][j - 1] + 2;递推公式:[i,j]的子串有两种情况:若s[i]==s[j],如果[i+1,j-1]的子串是回文串,那么[i,j]的子串也为回文串。在递归方程中,dp[i][j]有两个来源,首先是s[i]和s[j]相同的情况,dp[i][j]等于dp[i+1][j-1]+2也就是子序列去掉两边的字母的序列中最长回文子序列的长度+2,不相等的情况,等于不包含两边字母的两种情况中最大的那一个。

2024-01-05 10:34:59 536

原创 代码随想录训练营第五十六天| ● 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});因为 dp[i][j - 1] + 1 = dp[i - 1][j - 1] + 2,所以递推公式可简化为:dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1);583. 两个字符串的删除操作。

2024-01-04 14:19:54 562

原创 代码随想录训练营第五十五天| ● 392.判断子序列 ● 115.不同的子序列

类似,只不过那道题是求两个字符串的公共子序列,这个是判断一个短的字符串是否是另一个字符串的子序列,因此区别就在于当遍历到两字符串不相同的元素时,这道题只会将长的字符串的该元素跳过,子序列的该元素并不会跳过,即dp[i][j] = dp[i][j-1];这道题目算是 编辑距离问题 的入门题目(毕竟这里只是涉及到减法),慢慢的,后面就要来解决真正的 编辑距离问题了。但相对于刚讲过 392.判断子序列,本题 就有难度了 ,感受一下本题和 392.判断子序列 的区别。115.不同的子序列。

2024-01-03 14:53:56 361

原创 代码随想录训练营第五十三天| ● 1143.最长公共子序列 ● 1035.不相交的线 ● 53. 最大子序和 动态规划

以下是我写的代码,dp数组记录的是以nums[i]为结尾的最大连续子序列和,遍历过程中当最大和大于零时,加上nums[i]绝对是大于nums[i]的,因此以nums[i]结尾的最大连续子序列和就是max + nums[i],并重新记录max,若小于零,以nums[i]结尾的最大连续子序列和就是nums[i]了。dp[i][j]:长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列为dp[i][j],记录的是累计的最大长度。1143.最长公共子序列。

2024-01-03 09:56:17 425

原创 代码随想录训练营第五十二天| ● 300.最长递增子序列 ● 674. 最长连续递增序列 ● 718. 最长重复子数组

在后序遍历中,j为i之前的元素若dp[i]比dp[j]大的话dp[i]就取dp[i]和dp[j]+1中更大的那一个,这样就实现了递增序列个数的计算。本题相对于昨天的动态规划:300.最长递增子序列 最大的区别在于“连续”。概括来说:不连续递增子序列的跟前0-i 个状态有关,连续递增的子序列只跟前一个状态有关。今天开始正式子序列系列,本题是比较简单的,感受感受一下子序列题目的思路。使用二维dp数组进行两个序列的公共序列遍历。求连续递增序列只需与前一个元素比较即可。674. 最长连续递增序列。

2024-01-02 13:09:33 496

原创 代码随想录训练营第五十一天| ● 309.最佳买卖股票时机含冷冻期 ● 714.买卖股票的最佳时机含手续费 ●总结

相对122.买卖股票的最佳时机II ,本题只需要在计算卖出操作的时候减去手续费就可以了,代码几乎是一样的,可以尝试自己做一做。本题加了一个冷冻期,状态就多了,有点难度,大家要把各个状态分清,思路才能清晰。714.买卖股票的最佳时机含手续费。309.最佳买卖股票时机含冷冻期。股票问题做一个总结吧。

2024-01-01 16:15:37 407

原创 代码随想录训练营第五十天| ● 123.买卖股票的最佳时机III ● 188.买卖股票的最佳时机IV

一定是选最大的,所以 dp[i][1] = max(dp[i-1][0] - prices[i], dp[i - 1][1]);dp[i][j]中 i表示第i天,j为 [0 - 4] 五个状态,dp[i][j]表示第i天状态j所剩最大现金。所以dp[i][2] = max(dp[i - 1][1] + prices[i], dp[i - 1][2])那么dp[i][1]究竟选 dp[i-1][0] - prices[i],还是dp[i - 1][1]呢?本题是123.买卖股票的最佳时机III 的进阶版。

2024-01-01 11:03:57 395

原创 代码随想录训练营第四十九天| ● 121. 买卖股票的最佳时机 ● 122.买卖股票的最佳时机II

dp数组有两个维度,[0]表示当前持有股票,[1]表示当前不持有股票,而持有股票是由前面和本次的状态退导出来的,也就是之前就购买了还是这次购买的,选取数值更大的那一个即dp[i][0] = max(dp[i - 1][0], -prices[i]);未持有股票也一样,选取上次的状态和这次卖出后更大的那一个:dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);122.买卖股票的最佳时机II。121. 买卖股票的最佳时机。

2023-12-31 10:12:47 381

原创 代码随想录训练营第四十八天| ● 198.打家劫舍 ● 213.打家劫舍II ● 337.打家劫舍III

首先进行左右遍历得到左右子节点的遍历结果,根据左右子节点遍历结果来选取当前节点的偷或不偷。不偷时选取左右节点偷或不偷最大值之和,偷时,将当前节点的值加上左右节点不偷的值,返回一对偷或不偷的vector。较为简单,关键是递推公式:dp[i] = max((dp[i-2]+nums[i]), dp[i-1]);只需考虑第i个需不需要偷,如果第i-1个没有偷dp[i-2]和dp[i-1]就应该是相同的,dp[i-2]+nums[i]一定大于dp[i-1]。337.打家劫舍III。213.打家劫舍II。

2023-12-31 09:44:27 481

原创 代码随想录训练营第四十六天| ● 139.单词拆分 ● 关于多重背包,你该了解这些! ● 背包问题总结篇!

主要思路:将该题看做一完全背包问题,dp数组的含义是第i个元素之前是否能由字典中的元素组成。背包是字符串s,物品是字典。如果确定dp[j] 是true,且 [j, i] 这个区间的子串出现在字典里,那么dp[i]一定是true。所以递推公式是 if([j, i] 这个区间的子串出现在字典里 && dp[j]是true) 那么 dp[i] = true。关于多重背包,你该了解这些!

2023-12-30 11:36:54 501

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

由于是无限数量的金币,所以是完全背包问题,同时要求最小的数量,递推公式:dp[j] = min(dp[j - coins[i]] + 1, dp[j]);这道题与之前组合总和 Ⅳ是一样的,只不过换了个说法,楼层数即是背包数,能走的步数即是物品。本题 和 322. 零钱兑换 基本是一样的,大家先自己尝试做一做。这道题目 爬楼梯之前我们做过,这次再用完全背包的思路来分析一遍。如果求组合数就是外层for循环遍历物品,内层for遍历背包。如果求排列数就是外层for遍历背包,内层for循环遍历物品。

2023-12-30 10:56:24 554

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

同之前的目标和问题,只不过变为了完全背包问题,每个物品可以无限次放进背包。DP数组表示在容量为i的情况下能有几种方法,每个容量i都是根据放入物品的重量,将方法种类增加的。有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i]。背包容量的每一个值,都是经过 1 和 5 的计算,包含了{1, 5} 和 {5, 1}两种情况。,求解将哪些物品装入背包里物品价值总和最大。518. 零钱兑换 II。377. 组合总和 Ⅳ。

2023-12-14 22:13:58 390

原创 代码随想录训练营第四十三天| ● 1049. 最后一块石头的重量 II ● 494. 目标和 ● 474.一和零

动态规划之背包问题,这个背包最多能装多少?LeetCode:1049.最后一块石头的重量II_哔哩哔哩_bilibili代码随想录i++)i++)j--)这道题和昨天那道题类似,由于两个相碰的石头会剩下相差的重量,因此要将整个石堆按重量尽量平分,两堆相差的重量就是碰撞后剩下的最后一块石头的重量。因此本题物品的重量为stones[i],物品的价值也为stones[i],要放进容量为sum/2的背包中,最后返回两堆差值即可!

2023-11-22 17:06:54 60

原创 代码随想录训练营第四十二天| ● 01背包问题,你该了解这些! ● 01背包问题,你该了解这些! 滚动数组 ● 416. 分割等和子集

我采用了一维的方法来解决这道题,首先先求出总和,如果是奇数说明肯定不能平分。然后所要的target就是sum/2。创建一个target+1大小的dp数组进行遍历即可,最后dp[target]中的值就是nums中的所有元素选取后放入大小为target的背包的最大值,如果等于target说明nums能被平分。以上分析完,我们就可以套用01背包,来解决这个问题了。416. 分割等和子集。本题是 01背包的应用类题目。本题是 01背包的应用类题目。

2023-11-21 17:05:16 68

原创 代码随想录训练营第四十一天| ● 343. 整数拆分 ● 96.不同的二叉搜索树

这道题自己想是真想不出来,思路是n等于i时,他不同的二叉搜索树的数量等于以1为根节点的数量加以2为根节点的数量一直加到以i为根节点的数量。而以i为根节点的数量要由它不同的左右子树的数量相乘来得到。这道题的关键就是将dp[i]转换为 max(j * (i-j), j * dp[i-j]),也就是在分成两个数还有两个以上的数中的最大值,由于遍历的时候dp[i-j]已经是最大值了,所以只需要比较这两个值即可。可以进一步进行优化:因为拆分一个数n 使之乘积最大,那么一定是拆分成m个近似相同的子数相乘才是最大的。

2023-11-20 17:09:55 67

原创 代码随想录训练营第三十九天| ● 62.不同路径 ● 63. 不同路径 II

初始化:在初始化的过程中,如果第一行或第一列遇到了障碍,那这一行或这一列后面的所有地方都不应该到达,因此要在遍历的条件中加入&& obstacleGrid[0][i] == 0,当遇到障碍时停止初始化,又由于dp数组一开始都初始化为0了,障碍物后面的地方也都会是0满足要求。初始化时,将第一行和第一列都初始化为1,然后推导的过程中当前网格的路径数量就是其左边和上边的路径数量总和,根据这个推到公式即可推出到终点的路径数量!然后后面推导的过程中就相当于避开了障碍的这条路径,只计算了没有障碍的那条路径!

2023-11-19 21:06:32 659

原创 代码随想录训练营第三十八天| ● 理论基础 ● 509. 斐波那契数 ● 70. 爬楼梯 ● 746. 使用最小花费爬楼梯

可以认为最后是通过一步还是两步到达终点,如果是一步到达,那f(n)=f(n-1),如果是两步那f(n)=f(n-2),最后的方法应该是两种方式的总和f(n-1)+f(n-2)!一定是选最小的,所以dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);dp[i - 2] 跳到 dp[i] 需要花费 dp[i - 2] + cost[i - 2]。那么究竟是选从dp[i - 1]跳还是从dp[i - 2]跳呢?746. 使用最小花费爬楼梯。

2023-11-18 18:50:28 105

原创 代码随想录训练营第三十七天| ● 738.单调递增的数字 ● 968.监控二叉树 ● 总结

可以看看贪心算法的总结,贪心本来就没啥规律,能写出个总结篇真的不容易了。代码随想录。

2023-11-18 15:42:32 54

原创 代码随想录训练营第三十六天| ● 435. 无重叠区间 ● 763.划分字母区间 ● 56. 合并区间

这是我的代码,首先进行左边界的排序,然后初始化两个左右边界,在遍历的过程中进行边界判断,若当前元素的左边界大于现有右边界,说明边界不存在重合,因此要将当前边界加入结果之中,然后根据当前元素更新左右边界;之后进行遍历,在遍历的过程中,有一个左边界一个右边界,右边界随哈希数组的值进行更新,当右边界和索引相等时,说明已经到达了当前搜索区域的最右边界,就应该将当前边界记录至结果之中了,然后更新左边界继续遍历。示例代码是通过对结果数组最后一个元素(也就是当前区间的右边界)来进行对重叠边界的合并操作。

2023-11-17 16:11:51 50

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

十美元的情况下,需要用五美元找零,如果找不了则返回false;这是我的基础思路, 先找一个最右边界,然后在遍历的过程中更新这个最右边界。如果最右边界小于当前遍历到的元素的左边界,说明不能射爆这个气球了,需要再加一根箭同时更新最右边界,如果包含在最右边界内,则需要比较两个右边界,取最小的。因为已经排好序后,从身高最高的开始选起,所以选取后面的人的时候不会因为前面的身高比较矮而导致排队顺序不确定。示例代码,思路相同,只不过是在排序后比较相邻两个边界即可,比较当前范围左边界是否在上一个范围的右边界内。

2023-11-16 19:51:56 57

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

这道题需要现将绝对值大的负数变为正数,要是k还不为0的话,就要反复取反绝对值最小的正数,如果是偶数,就还是正数;如果是奇数,就该反转为负数了,最后求和即可。这道题需要先进行排序,使用自定义的sort方法,通过cmp方法来确定sort的排序方式。本题是根据绝对值由大到小进行排序!

2023-11-16 14:26:32 99

原创 代码随想录训练营第三十二天| ● 122.买卖股票的最佳时机II ● 55. 跳跃游戏 ● 45.跳跃游戏II

这道题与上道题相比,多了求最小的步数,也可采用与上道题类似的思路,通过最大范围来解决问题。但这道题要有两个范围,一个当前范围,一个下一步的范围。当遍历到当前范围而还没有到最后一个元素时,就要将步数加一然后更新当前范围,变为遍历过后能达到的最新的最远范围,直至到最后一个元素为止。遍历每个元素时,如果之前的范围可以覆盖到当前元素,则更新覆盖范围为原来和从这个元素中的最大值,然后继续遍历。如果最终遍历到了末尾元素仍在范围内,就返回true,如果途中就有不在范围内的元素的话就返回false。

2023-11-15 19:56:38 58

原创 代码随想录训练营第三十一天|● 理论基础 ● 455.分发饼干 ● 376. 摆动序列 ● 53. 最大子序和

局部最优:当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。这个四步其实过于理论化了,我们平时在做贪心类的题目 很难去按照这四步去思考,真是有点“鸡肋”。做题的时候,只要想清楚 局部最优 是什么,如果推导出全局最优,其实就够了。这道题使用贪心法还是有一点绕,具体思路看代码随想录吧,标记了,还得二刷。比较简单,排序后从大到小分发即可。全局最优:选取最大“连续和”

2023-11-15 17:04:13 36

原创 代码随想录训练营第三十天| ● 332.重新安排行程 ● 51. N皇后 ● 37. 解数独

在每个遍历过程中,由传入的row来确定遍历棋盘的行,在递归过程中+1的col来遍历棋盘的列,如果满足n皇后要求的话就将该处加入一个皇后,再进行的遍历。在遍历中,会判断每个每个由result末尾地点的起点是否存在航班,若存在航班就将它加入进结果中,同时将该航班的次数减少。}在初始化过程中,使用[]来直接对map进行初始化操作,若targets中没有该key,则会将value默认为0且进行++操作。首先呢,这道题回溯的返回值是bool,因为只需要一个结果,需要找到正确的结果后立刻返回,减少不必要的搜索。

2023-11-14 21:25:21 84

原创 代码随想录训练营第二十九天| * 491.递增子序列* 46.全排列* 47.全排列 II

在递归返回之后,回溯的过程只需要将path的元素弹出,而set中的元素由于是在每次循环中才创建的,记录每一层使用过的元素,而不是全局变量,因此不需要将其中的元素弹出!使用used数组来记录在每次循环中使用过的元素,每次循环(每一层)都是从0到size-1,会遍历整个数组,在每个枝干中寻找未添加的元素,添加完元素后会将used数组更新,回溯后要重置path及used。这道题也是需要用到去重技术,但由于这道题是要求递增子序列,因此不可以使用之前的先排序再使用数组来进行重复判断,而需要使用set来进行去重。

2023-11-13 20:29:40 130

原创 代码随想录训练营第二十八天| ● 93.复原IP地址 ● 78.子集 ● 90.子集II

首先是递归函数的参数,多了额外的pointNum用来记录加入'.'的数量。然后是终止条件,判断pointNum是否达到3了,如果达到了且最后一组分割也满足条件(判断是否满足条件的函数单独完成),就将这组分割存入结果之中。判断当前分割是否满足条件,若满足条件,在该分割后添加'.',同时进行下一层的递归,在递归结束之后还要将'.'清除,已达到回溯的效果。做了之前的题这道题就比较简单了,就是标准的回溯,由于是要全部的子集,只需要在每次递归函数的一开始将path放入结果之中即可。

2023-11-13 16:58:07 56

原创 代码随想录训练营第二十七天| ● 39. 组合总和● 40.组合总和II● 131.分割回文串

如果当前元素和前一个元素相同,且used数组等于false,则说明当前函数已经会在前一次遍历中被选取了,这个元素也就应当被跳过。不同的地方是,这次的回溯的startIndex是将分割集合的起始位置传入函数中,在遍历中判断从startIndex到i中间的子串是否满足回文串,若满足,则继续进行下一个位置的比较。同时可以进行同一个元素的多次选取,所以在递归的过程中要传入的参数是i就不需要i+1,这样就可以将本个元素重复地进行选取,同时也会随着i的增加而增加,这样就不会出现重复的组合了。我们来分析一下切割,

2023-11-12 17:34:45 45

原创 代码随想录训练营第二十五天| ● 216.组合总和III● 17.电话号码的字母组合

i++),在这里将i的值限定在能够满足k个元素的值当中,如果已经满足不了k个元素了,就不需要进行遍历了。我的做法,与组合总和类似,只不过加入了一个sum用来记录当前路径的总和。在遍历过程中,要加上sum+=i;s指的是累加的字符串,在每次递归中会增加在该次循环中得到的字母。在处理当前节点时,首先要取得当前数字,然后要根据当前数字来映射为字母,同时在递归函数中,index + 1, s + letters[i]这两个参数也就是进行了隐式的回溯。}操作属于终止条件,如果当前点和已经大于要求的和,直接返回。

2023-11-09 22:24:53 75

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

在终止条件中:path这个数组的大小如果达到k,说明我们找到了一个子集大小为k的组合了,在图中path存的就是根节点到叶子节点的路径。此时用result二维数组,把path保存起来,并终止本层递归。k - path.size()是当前路径还需要加入几个元素才满足要求,用n减去得到的是该层遍历应该遍历到哪里,加上1是因为在遍历中是使用i直接加入path中,而不是从0开始的下标,因此要加1来补位。单层搜索的过程:回溯法的搜索过程就是一个树型结构的遍历过程,使用for循环用来横向遍历,递归的过程是纵向遍历。

2023-11-09 20:23:09 156

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

自己的递归做法,由于是平衡二叉搜索树,所以数组中间的元素肯定是二叉树的根节点(这样才能保持平衡),因此,利用数组中间元素来构建二叉树。首先通过中间元素来当做根节点,然后使用左侧数组来构建左子树,使用右侧数组来构建右子树,这样就能构建出二叉搜索数了。修建二叉搜索树,需要利用二叉搜索树的特性,左子树小于父节点,右子树大于父节点。因此当前节点小于目标区域时,应该返回右子树(有可能满足条件);我使用了一个全局变量来记录累加的和,然后进行右中左的中序遍历,从最右下的节点一路累加,直至加完整棵树即可得到累加树。

2023-11-08 20:11:30 102 1

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

这道题运用了搜索二叉树的性质,如果是搜索二叉树,从上到下第一个搜到的在p、q节点中间的值的节点就是p、q两节点的最近公共祖先,具体推导可以看代码随想录。代码的思想是使用递归做法,如果左右节点不为空,说明左右子树的节点的值在p、q的值中间,也就是两节点的最近公共祖先了,直接返回即可。同时呢没改变root的值,最后直接返回root即可。自己的代码,采用了迭代法,从上至下遍历整颗树,直至找到插入元素应该在末尾插入的位置将其插入。本道题虽然不需要回溯,但最后要返回的是根节点,也是要搜索整个树,因此采用第二种写法。

2023-11-07 22:10:25 52

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

由于这道题也是二叉搜索树,可以进行中序遍历,如果连续两个值相同,则说明这个值存在至少两次,count次数++。如果到了maxCount,就将result数组更新,再重新进行加载众数。首先可以使用递归法,按照中序遍历搜索二叉树就是一个递增的序列,想要得到最小绝对差的话就只需要比较前后两个节点即可,所以需要一个全局变量pre来记录当前节点的前一个节点。采用后序遍历,终止条件为遇到空或遇到目标节点,然后先后遍历左右节点。在处理当前节点时要先判断左右子树是否存在目标节点,若存在则返回目标接地,否则返回NULL。

2023-11-07 20:33:03 40

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

其中maxVal实际上是要在遍历每个节点时更新的,也就是在遍历到每个节点时都要比它们的值小。这道题还可以,和上次构建二叉树思想差不多,我的思路是先找到最大值和最大值的索引,然后创建最大值的节点当做根节点,再递归的创建根节点的左右子节点。这是一开始的思路,单纯比较了父节点和左右子节点,这样是不对的,因为二叉搜索树指的是左子树的所有子节点的元素都小于父节点,右子树都大于!使用递归的方法可完成,实际上是两个数的同时递归,如果遇到了空节点,就返回另一个节点;如果不是空节点,则返回两节点之和。

2023-11-05 21:57:46 42

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

513.找树左下角的值一开始想到的就是层序遍历,使用迭代法进行遍历。只需要在层序遍历的过程中,只记录每层第一个元素,这样就能每层记录下第一个元素,在下一层将上一层的覆盖住,到最后一层就是树左下角的值了!在递归函数中,传入一个父节点、一个深度两个参数。由于在递归函数中,只需要对在终止条件时(即遍历到叶子结点时)进行判断修改结果值,所以没有对中间节点的判断,把这个遍历当做前序遍历还是后序遍历都可以。在终止条件时,对叶子结点的深度进行判断,如果大于现在的最大深度,则要更新最大深度和结果值以便下一次的判断。

2023-11-05 20:34:50 44

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

110.平衡二叉树本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。因此要求高度就应该使用后序遍历,从子结点往上计数。这道题的设计是getHeight函数,当有左右节点不是平衡二叉树的节点了,直接返回-1;当左右节点都是平衡二叉树,但组合起来就不是了,也返回-1;如果还符合平衡二叉树的话就返回当前节点的高度。最后在主函数中进行判断,如果不等于-1,则说明整棵树是一个平衡二叉树。

2023-11-02 22:55:47 98

原创 代码随想录训练营第十六天| ● 104.二叉树的最大深度 559.n叉树的最大深度● 111.二叉树的最小深度● 222.完全二叉树的节点个数

而使用递归法求高度可以用后序遍历,因为高度是从下向上计数的,后序遍历可以先计算左右子树的高度,然后将它们的值返回给其父节点,然后在计算父节点的高度,这样就完成了从下向上的这个过程!所以说一个节点没有右子节点有左子结点它的最小深度不是1,而是右子节点中的最小深度减一。使用层序遍历的话只需要判断当一个节点没有左右子节点时则说明这个节点是这个树的最小深度,只要返回这个深度即可得到答案。先求出该节点左右子树的高度,再将左右子树中高度最大的加一就是该根节点的深度,最后递归即可。求节点数量只需要在遍历过程中计数即可。

2023-10-31 22:25:13 100 1

原创 代码随想录训练营第十五天| ● 层序遍历 10 ● 226.翻转二叉树 ● 101.对称二叉树 2

使用队列完成的层序遍历代码如上,思路是遍历每一个元素,遍历到一个元素时将其入队,再将其左右子节点入队,每次遍历开始前记录队列当前大小,也就是该层元素的数量,创建一个这层元素的数组进行遍历,直至遍历完该层元素下一层的元素也已经全部入队,继续进行遍历。这道题使用了一个后序遍历的思路,先分别遍历左右节点的外侧节点和内侧节点,比较它们是否相同,在递归下去,若全都相同就说明这个二叉树是对称的。如果是中序遍历,由于遍历后不会遍历到左子树,只需要将第二次地递归的右子树改为左子树即可。递归法的层序遍历代码如上。

2023-10-31 21:05:49 86 1

空空如也

空空如也

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

TA关注的人

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