自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 代码随想录算法训练营一刷总结

经过了两个月的学习和写题,完成了代码随想录算法的一刷,正好大部分时间都在暑假,所以有比较多的时间来写。不过在9月份开学过后,结合保研的压力,每天刷题的时间还是比较紧张,不过还是坚持下来了,每一天(有时候是第二天凌晨)都在当天完成了任务,对动态规划、图论这些原来只有模模糊糊概念的题目有了实感。不过第一次做很多题目还是无法独立做出来,还是要看解答,后续还是要继续刷题。

2025-10-11 19:02:29 121

原创 代码随想录算法训练营第六十天|97. 小明逛公园 127. 骑士的攻击

首先明确dp数组的含义,dp[i][j][k]代表从i到j经过[1,...,k]的最短距离,而这个k要从k-1来推出来,分为经过k这个点和不经过k这个点来判断,不过这是实际上的遍历情况,而为了节约空间,可以不需要第三个维度,因为即使属于k-1的数据被k使用了(同一轮先更新的被后更新的用了)也不影响结果,所以我实际上使用的是dp[i][j],初始化的时候就先全部赋值成最大值,之后再根据输入修改(实际上是k=0的值,因为这时候没有中间节点),遍历顺序就是先按照k的值从小到大,之后i和j就无所谓了。

2025-10-04 17:29:25 250

原创 代码随想录算法训练营第五十九天|94. 城市间货物运输 I 95. 城市间货物运输 II 96. 城市间货物运输 III

思路:这道题的特别是在最多只能经过k个城市(算上起点和终点一共经过k+1条边),看起来只需要循环限制为k+1次,但实际上并不是,因为每一次的遍历可能会使用在这一轮遍历新修改的值,而不是上一轮修改后的值,导致并不是严格的k+1次,因此每一轮我们都要使用一个副本,复制一下开始时的minDist数组。之后还有一个队列优化的方法,因为只有被初始化(即赋值不是inf)的才会考虑,所以我们只需要把每一次加入的新节点加入队列就可以了,而当这个节点被使用过后要把visit数组改成false(因为可能需要重复经过这个点。

2025-10-04 00:27:37 177

原创 代码随想录算法训练营第五十七天|53.寻宝

思路:同样也是找最小生成树,kruskal的思路是先按照距离从小到大排序,然后将每个边的两个节点合成一个集合(使用并查集),遍历所有的边,如果两个节点已经属于同一个集合,那就不管了,否则就和为一个集合并将距离加入ans。思路:prim是用于构建最小生成树的,prim算法主要分为三步,首先找离最小生成树最近的节点,然后把这个节点加入最小生成树,之后把和这个节点直接相连的点的距离和原来存储最小距离相比较,看能否替代。53.寻宝kruskal。

2025-10-03 11:49:58 148

原创 代码随想录算法训练营第五十八天|117. 软件构建 47. 参加科学大会

接着找剩下的入度为0的事件。所以有两个优化的思路,一个是用邻接表代替邻接矩阵,另一个是用堆来存储每一个节点,可以自动弹出距离最近的节点,不需要重新寻找。堆使用的是heapq,添加的方法是heapq.heappush(堆名字,元组内容),排序的规则默认是元组中的第一个元素从小到大,弹出的方法是heapq.heappop()思路:dijkstra和prim其实思路比较一致,也是分为三步,首先找到离出发点最近的点,之后将这个点标注为已经过,之后再更新从这个点到所有点的距离,看有没有比之前的距离近。

2025-10-03 11:49:39 274

原创 代码随想录算法训练营第五十六天|108.冗余连接 109.冗余连接II

具体的方法是每经过一条边,设两个节点为u,v,首先判断v的父节点是否是v(注意这里是父节点而不是祖先节点),如果不是v,说明之前已经有一个父节点,说明同时出现了两个父节点,记录这个位置。如果还是v,那就将u变为v的父节点,之后判断u和v是否是同一集合,是同一集合就代表已经成环,同样记录。之后判断如果不存在两个父节点,那么冗余边一定是导致成环,就输出成环位置的边,存在再判断是否成环,如果有环那就输出不成环的另一条冗余边(因为只有一条冗余边,两个问题肯定是同一条边导致的),不成环就输出后来的那条。

2025-09-30 01:08:57 178

原创 代码随想录算法训练营第五十五天|107.寻找存在的路径

思路:这道题是并查集的模板题,并查集可以解决判断两个元素是否属于同一集合的问题。思路就是写出find和join,如果两个元素的父节点都是相同的,就说明属于同一集合,如果不相同,就将其中一个父节点的父节点定义为另一个父节点(注意是父节点间的操作)107.寻找存在的路径。

2025-09-29 19:39:39 110

原创 代码随想录算法训练营第五十三天|110.字符串接龙 105.有向图的完全可达性 106.岛屿的周长

思路:这道题要找最短的路径,所以使用bfs(如果使用dfs则需要遍历所有路径然后找最短的),将题目提供的list转换为无向图,如果只相差一个字符,则可以连接两个节点。思路:这道题不需要具体的找能否到达某个节点,而是如正常的dfs一样遍历整个地图,看看遍历完后的visit数组是否全是True,是就说明完全可达。思路:这道题不需要使用搜索,简单的遍历并找周围不是陆地的就可以了,不过需要注意超出边界位置没有0或者1,但也要计算为周长。105.有向图的完全可达性。

2025-09-27 21:40:55 113

原创 代码随想录算法训练营第五十二天|101.孤岛的总面积 102.沉没孤岛 103.水流问题 104.建造最大岛屿

思路:这道题主要的创新之处也是在于遍历的方式不同,题目要求从某一个点走到边界,我们反其道而行之,从边界遍历到中间的点。思路:这道题思路也略有抽象,需要先遍历一遍找出每个岛屿,对其编号并求出其面积,之后再遍历整个地图,找出每个为0的节点,并找出其四周若连接岛屿则加上其面积(要使用set来保证不会重复加上同一个岛屿)。每个岛屿的面积用dict来存储。思路:这道题学到的新东西有两个,一个是用2来代表非孤岛(引入新的状态),一个是从遍历的方式,即从边界上每个点开始进行dfs或bfs,可以保证每个非孤岛都会遍历到。

2025-09-27 00:06:37 248

原创 代码随想录算法训练营第五十一天|99.岛屿数量 深搜 99.岛屿数量 广搜 100.岛屿的最大面积

思路:同样的,这道题是广搜的模板题,不过其实我对广搜不熟悉,所以写起来挺费劲的。广搜和之前二叉树的层序遍历一样,都要使用队列。main函数的部分,其实和dfs相同,在进入了bfs之后,首先给自己的位置visit数组变成True,然后将这个位置加入队列,接下来遍历队列,将每个方向的合法新位置加入队列,直到队列为空。一个是cnt+1只会在判断合法后使用,第二个就是cnt如果要全局定义有两种方法,一是将cnt定义为一个数组,所有变化都发生在cnt[0]上,二是在dfs中定义nonlocal cnt。

2025-09-25 23:30:44 226

原创 代码随想录算法训练营第五十天|98. 所有可达路径

思路:这道题是dfs的模板题,所以大概记录一下dfs的步骤。第一步是寻找传递的参数,第二步是确定终止条件,第三步是如何递归。不过因为邻接矩阵中找寻有浪费,所以可以使用邻接表,方法是引入defaultdict。处理输入的方法有两个,第一种是邻接矩阵,另一种是邻接表。98. 所有可达路径。

2025-09-24 20:11:37 208

原创 代码随想录算法训练营第四十九天| 42. 接雨水 84.柱状图中最大的矩形

思路:这道题和上一题有些类似,不过是找到左边和右边第一个比当前高度小的位置,所以遍历的时候要存储位置而非高度,方法就是往左和右分别寻找,中间有一个减少的方法就是可以不一个个找,而是直接找那个位置对应的第一个小的位置。思路:这道题准备使用双指针的方法,每一列能储存的雨水数量就是左边最高和右边最高中低的那个减去当前的高度。不过每一次都往左右找是浪费,应该先分别从前到后和从后到前遍历一遍,来找到每个位置左边最高和右边最高。84.柱状图中最大的矩形。

2025-09-24 01:33:09 235

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

496.下一个更大元素 I。503.下一个更大元素II。

2025-09-22 23:25:49 216

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

递推则是先判断i和j位置上的字符是否相等,如果不相等那就不可能是回文子串(这里要求必须连续),相等有两种情况,一种是j和i相差小于等于1,那必然就是回文子串,如果大于1,那就要判断从i+1到j-1是否是回文子串,如果是,那新的也是。思路:这道题是子序列,所以是可以不连续的,所以dp数组代表i到j中的最长回文子序列。剩下就是和上一题比较类似,只不过这次是无论如何,一定存在回文子序列的,所以新的回文子序列是从原来的添加新的(如果i和j上的相等),不相等就是比不添加i或者不添加j那个更大。

2025-09-20 23:34:05 257

原创 代码随想录算法训练营第四十五天|115.不同的子序列 583. 两个字符串的删除操作 72. 编辑距离

递推的时候考虑有两种情况,一种是要选择s[i-1]这个位置,一种是不选择(例如s[i-1]和s[i-2]是一样的,那可以不一样),如果选择,那就是s[i-1][j-1],不选择就是s[i-1][j],因为这里是要求可能性的总和,所以这里就求和。思路:编辑距离和上一题的区别在于可能有增加和替换,不过增加word1可以代换为减少word2,所以实际上有变化的只有替换,替换操作会让word1[i-1]和word2[j-1]相等,所以就是在dp[i-1][j-1]的基础上+1。583. 两个字符串的删除操作。

2025-09-20 00:09:02 181

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

思路:这里的dp[i][j]表示在0-i-1和0-j-1之中的最长公共子序列,递推的方法是如果新的位置两个数组相等,那就是取dp[i-1][j-1]+1,不相等的话,那就取dp[i-1][j]和dp[i][j-1]的最大值。单说这道题还是很简单的,就是使用删除,dp[i][j]代表对应位置的长度,如果s[j]和t[i]相等,那么就dp[i][j]=dp[i-1][j-1]+1,否则就只修改i(代表删除了t中这个位置的字符)1143.最长公共子序列。1035.不相交的线。

2025-09-19 00:24:02 236 1

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

思路:这里的子数组就是连续子序列,这道题的dp[i][j]表示以nums1[i]和nums2[j]结尾的最长子数组的长度,递推的方法也比较简单,就是如果nums1[i]和nums2[j]的值相等,那就就dp[i-1][j-1]+1,初始化我是把i=0或j=0的情况全都计算了一遍,如果有相等就赋值为1,需要注意这里初始化的时候也要求一下max_len,防止后面没有重复子序列,直接使用最开始给max_len定义的0。不过这道题实际上不需要二维dp,只需要一维,而dp[i]代表以i为结尾的最长递增子序列。

2025-09-17 12:39:51 176

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

思路:因为有冷冻期这个概念,所以一共要设计出四种情况,一种是持有,剩下三种是不持有,分别是在这个位置卖掉,在前一个位置卖掉(处于冷冻期),在前一个位置之前卖掉(不处于冷冻期)。而dp[i][n]就代表在i的位置的n状态中的最大利润。递推公式为持有状态由前一个持有,前一个处于冷冻期,前一个不处于冷冻期三种取最大值得来,在当前位置卖掉必然由前一个持有加上当前的价格,处于冷冻期必然是由前一个位置卖出得来的,不处于冷冻期由前一个位置的不处于冷冻期和前一个位置是冷冻期中取最大值。714.买卖股票的最佳时机含手续费。

2025-09-16 20:38:14 209

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

思路:因为一共只能有一次操作,所以递归只有两种情况,当前持有和没持有,因此dp[i][0],dp[i][1]分别代表在i这个位置,持有和没持有股票的最大收益(需要注意持有并不代表一定要在当前买入,可能是之前买入的)。递推公式为,如果当前持有,那么就是之前持有或者在这一个位置购买的,两者取最大值。思路:这种情况要分为更多的情况,即没有购买,第一次持有,第一次出售,第二次持有,第二次出售,递推的公式也差不多,主要要注意的在于初始化的时候,,i=0的时候,第二次持有也是-prices[0]

2025-09-15 20:22:11 253

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

思路:这道题也是一种dp,dp[i]代表截止到第i-1个数可以打劫到多少钱,递推的方法是1、如果不打劫当前这家,那就是dp[i-1]的值(注意不代表一定会选i-1这个位置)2、如果打劫当前这家,那就是dp[i-2]+nums[i],两种可能取max即为新的dp值。递推公式是如果选的话,就是左子树和右子树各自的最大值(选或者不选),不选的话,就是当前节点的值和左子树不选,右子树不选的值。思路:这道题有两种可能,第一种是不选最后一个,第二种是不选第一个,然后分别计算两种的dp值,选取更大的那个。

2025-09-13 00:50:05 218

原创 代码随想录算法训练营第三十八天|322. 零钱兑换 279.完全平方数 139.单词拆分

dp[i]表示结尾为i的字符是不是满足单词拆分,返回值是bool,递推公式由两部分构成,一部分是不选择新进入的单词,那么就是之前的dp[i],而如果要选择的话,就需要dp[i-len(word)]并且从i-len(word)到i这部分就等于新的单词,这两种是or的情况。思路:这道题是一个组合的背包问题,区别是在于递推公式,在不取这个数的dp[j]和取这个数的dp[j-coins[i]]+1中最小值。初始化则是dp[0]=0,因为零钱为0的时候,最小需要零个硬币。

2025-09-12 15:35:42 208

原创 代码随想录算法训练营第三十七天|518. 零钱兑换 II 377. 组合总和 Ⅳ 70. 爬楼梯

今天的题目都是完全背包的问题,完全背包和01背包的区别在于一个元素能否多次使用,如果能够无限次使用就是完全背包,具体在代码之上,差别主要在于递推公式,当不选择这个新的物品时,就是dp[i-1][j],而当选择的时候,是dp[i][j-weight[i]],第一维是i因为可能会已经使用过当前这个物品。而在一维的情况下,遍历情况也有所不同,如果是单纯的取max,那就无所谓遍历顺序,因为不介意重复使用,而如果是求符合的种类数,就有讲究了。518. 零钱兑换 II。377. 组合总和 Ⅳ。

2025-09-11 22:51:43 250

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

思路:这道题和昨天的最后一题比较类似,只是不一定能够平分,但是要尽量平分,最后总和减去dp[result]*2。思路:这道题也是背包问题,只不过同时有两个变量要背包,即零的数量和一的数量,之后就是常规的一维背包问题。1049. 最后一块石头的重量 II。

2025-09-11 02:31:30 221

原创 代码随想录算法训练营第三十五天|背包问题 二维 背包问题 一维 46. 携带研究材料 416. 分割等和子集

递推公式分为两种可能,一种是不选择这个新增的,那就是dp[i-1][j],另一种如果要选择的话,那就要减去其重量并加上其价值,即dp[i-1][j-weight[i]]+value[i]。而初始化的部分,可以先把所有都赋值0,然后在只选择第0个物品的时候,当重量大于等于第0个时,就初始化其的价值。值得一提的是,可以在j<weight[i]时进行剪枝,因为当前的最大重量比新物品的小,不可能引入新的物品,直接等于i-1的情况。分为二维背包和一维背包,区别在于dp数组是几维的。46. 携带研究材料。

2025-09-09 15:03:47 291

原创 代码随想录算法训练营第三十四天|62.不同路径 63. 不同路径 II 343. 整数拆分 96.不同的二叉搜索树

思路:主要的困难之处在于如何找到递归公式,dp[i]表示有1-i个节点的二叉搜索树的数量,那有i个树可以做根节点,以i=3为例,根节点为1,左无右2、3,根节点为2,左1右3,根节点为3,左1、2右无,可以表示为dp[0]*dp[2]+dp[1]*dp[1]+dp[2]*dp[0],所以说就是从j=0循环到j=i,而初始化只需要dp[0]=1。思路:这道题和上一题本质上是一样的,只需要在有障碍物的位置把可能性清零就可以,不过需要注意这种清零的判断要放在给[1,1]初始化之前,否则会有一个样例不过。

2025-09-08 18:12:52 254

原创 代码随想录算法训练营第三十二天|509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯

思路:这道题的本质和前面两道差不多,只是定义上有点奇怪,走到顶部实际上是要越过顶部,所以为了理解的方便,我定义的dp数组和题目要求略有不同,dp[i]代表走到第i级楼梯使用的最小花费,而递推的方法dp[i]=min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]),比较便于理解,初始化也依据题意,dp[0],dp[1]都为0,之后从前往后遍历即可。不过这道题实际上我没有使用dp,而是用了递归,以后不会这样了。由此可以完成如下的dp代码。509. 斐波那契数。

2025-09-06 09:53:35 123

原创 代码随想录算法训练营第三十一天|56. 合并区间 738.单调递增的数字 968.监控二叉树

首先是一共有三种情况,第一种是放置监控,剩下两种都是没放置监控,一种是被监控覆盖,一种是没被覆盖。1、如果两个节点都是被监控覆盖,那当前节点就应该是无需被覆盖2、如果有一个是不被覆盖,那么当前节点就得是放置监控3、如果有一个是放置了监控,那当前节点就是被覆盖了(注意顺序不能反,例如一个空,一个放置监控,当前节点也得放监控)思路:这道题和昨天的重叠区间处理方法差不多,需要判断新的区间和之前的区间是否有重合,如果有就要更新end,如果没有就将原来的start和end输入到result。738.单调递增的数字。

2025-09-05 22:24:38 229

原创 代码随想录算法训练营第三十天|452. 用最少数量的箭引爆气球 435. 无重叠区间 763.划分字母区间

第二种方法本质上也类似,不过操作起来更简单一些,就是只需要存储每个字母出现的最后一次的位置,然后遍历字符串,将每一个遇到的字符的最后一次出现和end比较谁大,大的存为end,直到这个位置等于end,说明这个区间已经完整了,之前出现过的字符在后面不会再出现,存入result。然后,要找出每个重叠区间的最右端。首先是要对新的区间进行判断,如果左界已经大于原来的右界,那说明需要引入新的箭,否则就会有重叠区间,把当前区间的右界设为重叠区间的右界(方便后面使用,而不是说实际上的界限改变了)435. 无重叠区间。

2025-09-04 22:08:26 196

原创 代码随想录算法训练营第二十九天|134. 加油站 135. 分发糖果 860.柠檬水找零 406.根据身高重建队列

首先先把高的排序前面,如果身高一样就把k值小的放在前面。然后第二次把排序好的数列按顺序添加到自己的k值所在的位置,如果新加的位置和之前重复,那就会把原来的位置及之后所有的数后移一格。思路:如果总加的油大于总消耗量,那么就可以完成任务,那就从头开始遍历,如果累积的小于0,那么就代表不能从这里开始,直到找到可以到结尾还大于零的,就说明可以以这个为起点。思路:使用两遍的遍历,从左往右一遍,再从右往左一遍,如果比之前的大就+1,因为从右往左不会把值变小,只有可能变大,所以不会改变从左到右完成的内容。

2025-09-03 22:59:16 263

原创 代码随想录算法训练营第二十八天|122.买卖股票的最佳时机II 55. 跳跃游戏 45.跳跃游戏II 1005.K次取反后最大化的数组和

思路:这道题的关键是想到把相隔几天的出售转化为每一天的出售,例如第一天买,第三天卖,可以转化为第一天买,第二天卖,第二天买,第三天卖,所以说只需要统计每一天和前一天比的差值,如果能赚的钱大于0就视为买入,如果<=0,那就不买入。思路:这道题感觉不能算贪心了,就是先排序,看能否把所有负数的取反,如果k的数量小于负数的数量就取反,如果超过,看超过的是奇数还是偶数,偶数就不管,奇数就把新的数组先重新排序,再把最小的取反。1005.K次取反后最大化的数组和。122.买卖股票的最佳时机II。

2025-09-02 23:03:09 323

原创 代码随想录算法训练营第二十六天|455.分发饼干 376. 摆动序列 53. 最大子序和

思路:这道题的思路还是比较奇怪的,就是使用cnt存储当前的和,如果这个和大于result,那就将这个和存入result,而如果这个和<=0(注意不是当前的值<=0),就把cnt变为0,注意这两个判断的先后不能反,否则如果全部是负数就会错误。思路:这道题的思路还是比较顺的,首先将两个数组排序,index标记胃口数组,然后遍历饼干数组,紧接着遍历胃口,如果饼干能满足胃口,就将index+1。最后看能满足几个胃口,就返回这个值。

2025-09-02 00:16:19 211

原创 代码随想录算法训练营第二十五天|491.递增子序列 46.全排列 47.全排列 II 51.N皇后 37.解数独

思路:和上一题的区别在于需要去重,去重也是和之前差不多,先排序,然后当nums[i]==nums[i-1]并且used[i-1]==0时,也就是和前一个相同并且前一个没有被使用过,注意这个used[i-1]==0,说明是同一层重复而不是同一枝上重复。思路:因为这道题不能将数组进行排序,所以不能通过之前的去重方法,而是要使用set,来存放已经用过的数字,不过需要注意的是,uset是每一次调用backstring重新定义的,每一层调用都是一个单独的uset。

2025-08-30 23:32:43 323

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

思路:这道题和之前不同的是,不是达成一定条件才会加入result,而是遍历过的每个节点都加入result。思路:这道题和昨天的分割没什么区别,只有一点是需要排除有前导0的可能,判断方法是长度大于1且首位为0。思路:这道题就是前面的子集再加上去重的处理,去重是之前使用过的方法。

2025-08-29 21:07:52 223

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

思路:首先第一步是要想到怎么用回溯解决分割问题,其实就是和之前差不多,遍历到的位置就是当前字符串结束的位置,如果从start到当前这个位置的子串是回文串,就添加到path,而当start的值等于len(s)的时候,代表走完一次了,就将path添加到result中。判断回文串的方法一个是使用双指针,还有一个就是直接反转子串s[::-1]来判断是否相等。思路:这题和之前的区别在于给定的数组内部可能会有重复,所以需要去重,使用的方法就是先排序,然后在for循环遍历的时候,如果新的起始点值和前一个一样,就跳过。

2025-08-28 20:29:57 210

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

思路:这道题和前面有一些不同,一个是在于要设计一个数组表示数字和字母的对应,还有一个就是横向的循环是这个字母数组的遍历,竖向的是digits数组的顺序。思路:这道题是回溯问题的模板题,实际执行的方法参考如下的图片,横向使用for循环,每一个循环之中向深处遍历。回溯的处理是pop掉path最后的字符。然后要学习的是剪枝的处理,深度遍历开始的位置不用一直到最后一个数,而是只用到n-(k-len(path))+1。思路:这道题和前面的组合差不多,不过是回溯的除了path,还有数值的总和。216.组合总和III。

2025-08-27 12:31:07 375

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

思路:这道题递归的代码还是比较简洁的,不过需要注意的是,不能套用之前删除节点时的方法,因为如果一个节点不在区间内,那整个左子树或者右子树都不在,明白了这个就可以比较快的写出来了。思路:不同于平常的遍历方法,这道题需要用反中序遍历,因为越右的值越大,才能加入到累加之中,所以需要一个pre来储存累加值。思路:这道题还是比较简单的,就是找出最中间的值,然后不断向两侧递归就可以了。108.将有序数组转换为二叉搜索树。538.把二叉搜索树转换为累加树。669. 修剪二叉搜索树。

2025-08-26 12:01:30 230

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

第二种整体思路也差不多,但是不用整体移动,而是把当前的根节点的值和右节点的最左下节点的值对换,不过在这里并没有删除原来的节点,而是把要删除的节点移到叶子节点的位置,等到遍历到的时候再删除。思路:利用二叉搜索树的性质,寻找最近的公共祖先会相对容易,因为这个公共祖先的大小肯定是在p和q之间的,所以只要在遍历二叉树的时候,第一次找到的值位于p和q之间,就是公共祖先。思路:需要注意的是,二叉搜索树中的插入不需要修改二叉树的结构,只需要在叶子节点添加就可以了,不要被题目的示例误导了。450.删除二叉搜索树中的节点。

2025-08-25 17:28:27 385

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

思路:因为二叉搜索树的性质,所以数值相同的节点在中序遍历中必然相邻,所以只需要用一个指针存放pre前一个节点,然后比较一下当前的值和pre是否相同,如果相同,就cnt+1,不相同就cnt=1.不过这道题有几个地方得注意,一个是python中作用域导致同时在定义的函数内外修改同一个变量会报错,要加上self,还有一个就是这道题的众数可能有很多个,所以如果频率变大了,需要把原来的结果清空。处理的方法就是如果两个只有左或者右返回不为空,那就取这个返回值,如果都不为空,那就返回目前的节点。

2025-08-23 17:11:25 348

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

思路:利用二叉搜索树必须得使用中序遍历,因为上一题提到的性质,左中右必然是递增的。第二种方法本质上类似,也是使用中序遍历,不过会增加一个全程存在的变量max_val,因为二叉搜索树的性质,所以每一个递归到的节点必须大于当前的最大值,然后将自己的值赋值给最大值,否则就返回False。思路:这道题可以主要依靠一颗树,如果两个节点都存在,就将值加到第一颗树上,需要注意的是,如果1不存在,就返回2,而如果2不存在,就返回1(不用专门写都不存在,因为刚刚的就会返回None)700.二叉搜索树中的搜索。

2025-08-22 17:27:45 228

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

思路:第一次引入了构建二叉树,主要的困难在于如何拆分新的区间,通过前序或者后序确定目前的根节点,再根据中序找到对应的位置,根据这个位置把中序拆分成左右两个区间,而前序或者后序的数组,因为左右子树长度的区间都是一样的,所以根据刚刚获取的两个区间长度来对前序或后序进行拆分。思路:112只要求找有没有路径,所以递归的返回值应该是bool,所以就是如果找到路径,就返回true,不是叶子节点就递归到两个子节点,有一个能返回true就可以。而如果直接使用层序遍历的话,就更简单,每一层直接把第一个数来赋值。

2025-08-21 20:53:41 167

空空如也

空空如也

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

TA关注的人

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