- 博客(54)
- 收藏
- 关注
原创 代码随想录算法训练营总结篇
0基础小白,从力扣给我答案我都完全看不懂不知道什么意思,到代码随想录看笔记和视频,理解思路,背下来代码再重新写,这样一直坚持持续了2个月。作为算法小白训练营期间的每天都很痛苦,完全不会写,还要去理解,但也会因为看懂一道题而也会有点小开心,感觉一天没有浪费,这也是代码的浪漫之处。未来规划,虽然跟着一刷了,但是所有题目都是背的没有形成自己的解题思维,应该很快会忘了。也发愁还没学会自己去独立思考解决问题。训练营结束后会二刷,重新在去理解算法思维,前行道路还很艰巨,万丈高楼平地起,要继续努力,自己还很大的不足。
2025-05-07 00:02:06
241
原创 代码随想录算法训练营第六十一天 | floyd算法
把k 赋值为 0,本题节点0是无意义的,节点是从1 到 n,在下一轮计算的时候,就可以根据 grid[i][j][0] 来计算 grid[i][j][1],此时的 grid[i][j][1] 就是 节点i 经过节点1 到达 节点j 的最小距离了。即: grid[i][j][k] = min(grid[i][k][k - 1] + grid[k][j][k - 1], grid[i][j][k - 1])第二种情况,grid[i][j][k] = grid[i][j][k - 1]3、dp数组如何初始化。
2025-04-28 22:51:43
365
原创 代码随想录算法训练营第六十天 | 1.ford判断负权回路 卡码网95.城市间货物运输II
在没有负权回路的图中,松弛 n 次以上 ,结果不会有变化,但本题有负权回路,如果松弛 n 次,结果就会有变化了,因为有负权回路 就是可以无限最短路径(一直绕圈,就可以一直得到无限小的最短距离);节点数量为n,起点到终点,最多是n-1条边相连。对所有边松弛一次,相当于计算起点到达与起点一条边相连的节点的最短距离,那么对所有边松弛 k + 1次,就是求 起点到达 与起点k + 1条边相连的节点的最短距离。思路:最多经过k个城市的条件下,而不是一定经过k个城市,也可以经过的城市数量比k小,但要最短的路径。
2025-04-27 22:33:24
220
原创 代码随想录算法训练营第五十八天 | 1.拓扑排序精讲 2.dijkstra(朴素版)精讲 卡码网117.网站构建 卡码网47.参加科学大会
节点0 的入度为0 出度为2, 也就是没有边指向它,而它有两条边是指出去的。节点的入度表示有多少条边指向它,节点的出度表示有多少条边从该节点出发。做拓扑排序的时候,应该优先找入度为0的节点,只有入度为0,它才是出发节点。如果发现结果集元素个数不等于图中节点个数,我们就可以认定图中一定有有向环,这也是拓扑排序判断有向环的方法。最短路算法中的 dijkstra 算法:在有权图(权值非负数)中求从起点到其他节点的最短路径算法。dijkstra 算法 同样是贪心的思路,不断寻找距离 源点最近的没有访问过的节点。
2025-04-25 22:54:53
494
原创 代码随想录算法训练营第五十七天 | prim算法和kruskal算法精讲 卡码网53.寻宝
根据minDist数组,选组距离生成树最近的节点加入生成树,那么minDist数组里记录的其实也是最小生成树的边的权值。最后我们就生成了一个最小生成树,绿色的边将所有节点链接到一起,并且保证权值是最小的,因为我们在更新minDist数组的时候,都是选距离最小生成树最近的点加入到树中。minDist数组用来记录每一个节点距离最小生成树的最近距离,来寻找距离最小生成树最近的节点,加入到最小生成树,刚开始还没有最小生成树,所以随便选一个节点加入就好。1、第一步:选距离生成树最近节点。1、用什么结构来记录。
2025-04-24 22:43:36
485
原创 代码随想录算法训练营第五十六天 | 108.冗余连接 109.冗余连接II
从前向后遍历每一条边(因为优先让前面的边连上),边的两个节点如果不在同一个集合,就加入集合(即:同一个根节点),如果边的两个节点已经出现在同一个集合里,说明着边的两个节点已经连在一起了,再加入这条边一定就出现环了。有向树的性质,如果是有向树的话,只有根节点入度为0,其他节点入度都为1(因为该树除了根节点之外的每一个节点都有且只有一个父节点,而根节点没有父节点)。思路: 题目说是无向图,返回一条可以删去的边,使得结果图是一个有着N个节点的树,如果有多个答案,则返回二维数组中最后出现的边。
2025-04-23 00:04:19
307
原创 代码随想录算法训练营第五十五天 | 107.寻找存在的路径
(3)判断两个节点是否在同一个集合,函数:isSame(int u, int v),就是判断两个节点是不是同一个根节点。(2)将两个节点接入到同一个集合,函数:join(int u, int v),将两个节点连在同一个根节点上。并查集可以解决:主要就是集合问题,两个节点在不在一个集合,也可以将两个节点添加到一个集合中。(1)寻找根节点,函数:find(int u),也就是判断这个节点的祖先节点是哪个。最后 isSame(int u, int v) 判断是否是同一个根就可以了。有边连在一起,就算是一个集合。
2025-04-22 00:30:18
281
原创 代码随想录算法训练营第五十三天 | 105.有向图的完全可达性 106.岛屿的周长
如果我们是处理当前访问的节点,当前访问的节点如果是 true ,说明是访问过的节点,那就终止本层递归,如果不是true,我们就把它赋值为true,因为这是我们处理本层递归的节点。首先明确,本题中什么叫做处理,visited数组来记录访问过的节点,该节点默认数组里元素都是false,把元素标记为true就是处理本节点了。(什么时候需要回溯操作,当我们需要搜索一条可行路径的时候,就需要回溯操作了,因为没有回溯,就没法“调头”。计算出总的岛屿数量,边的总的变数为:岛屿数量 * 4,1.确认递归函数,参数。
2025-04-20 19:41:22
428
原创 代码随想录算法训练营第五十二天 | 101.孤岛的总面积 102.沉没孤岛
思路: 本题要求找到不靠边的陆地面积,那么我们只要从周边找到陆地然后通过 dfs或者bfs 将周边靠陆地且相邻的陆地都变成海洋,然后再去重新遍历地图,统计此时还剩下的陆地就可以了。
2025-04-19 22:41:52
147
原创 代码随想录算法训练营第五十一天 | 99.岛屿数量 深搜 99.岛屿数量 广搜 100.岛屿的最大面积
(2)dfs函数终止条件写在了调用dfs的地方,如果遇到不合法的方向,直接不会去调用dfs;下一个节点是否能合法已经判断完了,传进dfs函数的就是合法节点。遇到一个没有遍历过的节点陆地,计数器就加一,然后把该节点陆地所能遍历到的陆地都标记上。在遇到标记过的陆地节点和海洋节点的时候直接跳过。这样计数器就是最终岛屿的数量。(1)把节点陆地所能遍历到的陆地都标记上,可以使用 DFS,BFS或者并查集。
2025-04-18 21:01:00
347
原创 代码随想录算法训练营第五十天 | 98.所有可达路径
首先是要找到 x节点指向了哪些节点,遍历节点x链接的所有节点找到x链接的节点;接下来就是将选中的x所指向的节点,加入到单一路径来;最后就是回溯的过程,撤销本次添加节点的操作。需要存一个目前我们遍历的节点,定义为x;还需要存一个n,表示终点,我们遍历的时候,用来判断当 x==n 时候 标明找到了终点。思路: 给定一个有n个节点的有向无环图,节点编号从1到n,请编写一个程序,找出并返回所有从节点1到节点n的路径。当目前遍历的节点为最后一个节点n的时候就找到了一条从出发点到终止点的路径。1.确认递归函数参数。
2025-04-17 20:25:38
288
原创 代码随想录算法训练营第四十九天 | 42.接雨水 84.柱状图中最大的矩形
此时的栈顶元素st.top(),就是凹槽的左边位置,下标为st.top(),对应的高度为height[st.top()],当前遍历的元素i,就是凹槽右边的位置,下标为i,对应的高度为height[i](栈顶和栈顶的下一个元素以及要入栈的元素,三个元素来接水!b.使用单调栈内元素的顺序,从栈头(元素从栈头弹出)到栈底的顺序应该是从小到大的顺序,因为一旦发现添加的柱子高度大于栈头元素了,此时就出现凹槽了,栈头元素就是凹槽底部的柱子,栈头第二个元素就是凹槽左边的柱子,而添加的元素就是凹槽右边的柱子;
2025-04-16 22:18:38
653
原创 代码随想录算法训练营第四十八天 | 739.每日温度 496.下一个更大元素I 503.下一个更大元素II
顺序的描述为从栈头到栈底的顺序,要使用递增循序(再强调一下是指从栈头到栈底的顺序),因为只有递增的时候,栈里要加入一个元素i的时候,才知道栈顶元素在数组中右面第一个比栈顶元素大的元素是i。情况二:当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况,如果相等的话,依然直接入栈,因为我们要求的是右边第一个比自己大的元素,而不是大于等于。如果要入栈的元素比栈顶元素大,更新此时栈顶元素下标对应的结果,然后弹出去,如果还比栈顶元素大,还一直弹,直到没有比他大的了,然后入栈。
2025-04-15 19:39:11
794
原创 代码随想录算法训练营第四十六天 | 647.回文子串 516.最长回文子序列
(2)如果s[i]与s[j]不相同,说明s[i]和s[j]的同时加入并不能增加[i,j]区间回文子序列的长度,那么分别加入s[i]、s[j]看看哪一个可以组成最长的回文子序列。(1)如果s[i]与s[j]相同,那么dp[i][j] = dp[i + 1][j - 1] + 2;那么dp[i][j]一定是取最大的,即:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);dp[i][j]:字符串s在[i, j]范围内最长的回文子序列的长度为dp[i][j]。
2025-04-13 00:15:06
415
原创 代码随想录算法训练营第四十五天 | 115.不同的子序列 538.两个字符串的删除操作 72.编辑距离
从如下四个递推公式:dp[i][j] = dp[i - 1][j - 1]、dp[i][j] = dp[i - 1][j - 1] + 1、dp[i][j] = dp[i][j - 1] + 1、dp[i][j] = dp[i - 1][j] + 1,可以看出dp[i][j]是依赖左方,上方和左上方元素的,所以在dp矩阵中一定是从左到右从上到下去遍历。所以当s[i - 1] 与 t[j - 1]相等时,dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
2025-04-12 13:45:43
1012
原创 代码随想录算法训练营第四十四天 | 1143.最长公共子序列 1035.不相交的线 53.最大子序和 392.判断子序列
此时相当于t要删除元素,t如果把当前元素t[j - 1]删除,那么dp[i][j] 的数值就是看s[i - 1]与 t[j - 2]的比较结果了,即:dp[i][j] = dp[i][j - 1];(2)如果text1[i - 1]与text2[j - 1]不相同,那就看看text1[0, i - 2]与text2[0, j - 1]的最长公共子序列 和 text1[0, i - 1]与text2[0, j - 2]的最长公共子序列,取最大的。同理dp[0][j]也是0。
2025-04-11 17:51:55
771
原创 代码随想录算法训练营第四十三天 | 300.最长递增子序列 674.最长连续递增子序列 714.买卖股票的最佳时机含手续费
根据dp[i][j]的定义,dp[i][0] 和dp[0][j]其实都是没有意义的,但dp[i][0] 和dp[0][j]要初始值,因为为了方便递归公式dp[i][j] = dp[i - 1][j - 1] + 1;dp[i][j] :以下标i - 1为结尾的A,和以下标j - 1为结尾的B,最长重复子数组长度为dp[i][j](特别注意: “以下标i - 1为结尾的A” 标明一定是 以A[i-1]为结尾的字符串 )dp[i][j]的定义也就决定着,我们在遍历dp[i][j]的时候i 和 j都要从1开始。
2025-04-10 13:58:06
657
原创 代码随想录算法训练营第四十二天 | 188.买卖股票的最佳时期IV 309.买卖股票的最佳时机含冷冻期 714.买卖股票的最佳时机含手续费
(1)达到买入股票状态(状态一)即:dp[i][0],有两个具体操作:操作一:前一天就是持有股票状态(状态一),dp[i][0] = dp[i - 1][0],操作二:今天买入了,有两种情况:前一天是冷冻期(状态四),dp[i - 1][3] - prices[i],前一天是保持卖出股票的状态(状态二),dp[i - 1][1] - prices[i]。选最大的,所以 dp[i][1] = max(dp[i - 1][0] - prices[i], dp[i - 1][1]);
2025-04-09 17:10:05
695
原创 代码随想录算法训练营第四十一天 | 121.买卖股票的最佳时期 122.买卖股票的最佳时机II 123.买卖股票的最佳时机III
(注意这里和121. 买卖股票的最佳时机唯一不同的地方,就是推导dp[i][0]的时候,第i天买入股票的情况,在121题中,因为股票全程只能买卖一次,所以如果买入股票,那么第i天持有股票即dp[i][0]一定就是 -prices[i];同样dp[i][1]取最大的,dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);一定是选最大的,所以 dp[i][1] = max(dp[i-1][0] - prices[i], dp[i - 1][1]);
2025-04-08 16:43:37
660
原创 代码随想录算法训练营第三十九天 | 198.打家劫舍 279.完全平方数 139.单词拆分
如果偷第i房间,那么dp[i] = dp[i - 2] + nums[i] ,即:第i-1房一定是不考虑的,找出 下标i-2(包括i-2)以内的房屋,最多可以偷窃的金额为dp[i-2] 加上第i房间偷到的钱。递推公式的基础就是dp[0] 和 dp[1],dp[0] 一定是 nums[0],dp[1]就是nums[0]和nums[1]的最大值即:dp[1] = max(nums[0], nums[1]);dp[i] 是根据dp[i - 2] 和 dp[i - 1] 推导出来的,那么一定是从前到后遍历。
2025-04-06 13:11:50
742
原创 代码随想录算法训练营第三十八天 | 322.零钱兑换 279.完全平方数 139.单词拆分
其他下标非0的元素都是应该是最大值,考虑到递推公式的特性,dp[j]必须初始化为一个最大的数,否则就会在min(dp[j - coins[i]] + 1, dp[j])比较的过程中被初始值覆盖。要选择最小的dp[j],和上题一样所以递推公式:dp[j] = min(dp[j - i * i] + 1, dp[j]);一维递推公式:dp[j] = min(dp[j - coins[i]] + 1, dp[j]);二维dp[i][j]=min(dp[i-1][j],dp[i][j-coins[i]]+1)
2025-04-05 20:42:08
725
原创 代码随想录算法训练营第三十七天 | 518.零钱兑换II 377.组合总和IV 70.爬楼梯(进阶)
二维dp 递推公式: dp[i][j] = dp[i - 1][j] + dp[i][j - coins[i]]二维dp 递推公式:dp[i][j]=dp[i-1][j]+dp[i][j-nums[i]]压缩成一维去掉前面,dp[i]有几种来源,dp[i - 1],dp[i - 2],dp[i - 3] 等等,即:dp[i - j]递推公式为:dp[i][j] = dp[i - 1][j] + dp[i][j - coins[i]];一维递推公式:dp[j]=dp[j]+dp[j-nums[i]];
2025-04-04 19:34:27
783
原创 代码随想录算法训练营第三十六天 | 1049.最后一块石头的重量II 494.目标和 474.一和零
dp[i][j] 就可以是 dp[i - zeroNum][j - oneNum] + 1,然后我们在遍历的过程中,取dp[i][j]的最大值。去掉维度i 之后,递推公式:dp[j] = dp[j] + dp[j - nums[i]] ,即:dp[j] += dp[j - nums[i]]二维DP数组递推公式: dp[i][j] = dp[i - 1][j] + dp[i - 1][j - nums[i]];dp[i][j]:最多有i个0和j个1的strs的最大子集的大小为dp[i][j]。
2025-04-03 16:35:18
975
原创 代码随想录算法训练营第三十五天 | 416.分割等和子集
放物品i:背包空出物品i的容量后,背包容量为j - weight[i],dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]且不放物品i的最大价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值。递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);从dp[j]的定义来看,首先dp[0]一定是0。
2025-04-02 23:02:39
334
原创 代码随想录算法训练营第三十四天 | 62.不同路径 63.不同路径II 343.整数拆分
代码里for循环的终止条件,一旦遇到obstacleGrid[i][0] == 1的情况就停止dp[i][0]的赋值1的操作,dp[0][j]同理。首先dp[i][0]一定都是1,因为从(0, 0)的位置到(i, 0)的路径只有一条,那么dp[0][j]也同理。因为从(0, 0)的位置到(i, 0)的路径只有一条,所以dp[i][0]一定为1,dp[0][j]也同理。dp[i][j] :表示从(0 ,0)出发,到(i, j)有dp[i][j]条不同的路径。1.确定dp数组以及下标的含义。
2025-04-01 21:58:50
463
原创 代码随想录算法训练营第三十二天 | 509.斐波那契数 70.爬楼梯 746.使用最小花费爬楼梯
dp[i - 1],上i-1层楼梯,有dp[i - 1]种方法,还有就是dp[i - 2],上i-2层楼梯,有dp[i - 2]种方法,dp[i]是两种方法之和,所以dp[i] = dp[i - 1] + dp[i - 2]dp[i - 1] 跳到 dp[i] 需要花费 dp[i - 1] + cost[i - 1],dp[i - 2] 跳到 dp[i] 需要花费 dp[i - 2] + cost[i - 2]。dp[i]是依赖 dp[i - 1] 和 dp[i - 2],遍历的顺序一定是从前到后遍历的。
2025-03-30 18:00:38
1043
原创 代码随想录算法训练营第三十一天 | 56.合并区间 738.单调递增的数字 968.监控二叉树
按照左边界从小到大排序之后,如果 intervals[i][0] <= intervals[i - 1][1] 即intervals[i]的左边界 <= intervals[i - 1]的右边界,则一定有重叠。思路:输入:intervals = [[1,4],[4,5]] 输出:[[1,5]] 解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。每个节点可能有几种状态:0:该节点无覆盖 1:本节点有摄像头 2:本节点有覆盖。左孩子有覆盖,右孩子有覆盖,此时中间节点应该就是无覆盖的状态了。
2025-03-29 17:51:18
524
原创 代码随想录算法训练营第三十天 | 452.用最少数量的箭引爆气球 435.无重叠区间 763.划分字母区间
2.如果当前区间的左边界<上一个区间的右边界,说明区间有重叠,将当前区间的右边界改为两个重叠区间右边界最小的;因为遍历进入下个区间,前两个区间有重叠,下个区间左边界与前两个区间重叠右边界最小的比较(因为前两个重叠区间移除一个),有重叠说明下个区间也是重叠。思路:输入: intervals = [[1,2],[2,3],[3,4],[1,3]] 输出: 1 解释: 移除 [1,3] 后,剩下的区间没有重叠。1.如果当前气球区间左边界>上个气球区间右边界,两气球区间没有重叠,需要两个箭引爆气球;
2025-03-28 15:41:36
561
原创 代码随想录算法训练营第二十九天 | 134.加油站 135.分发糖果 860.柠檬水找零 406.根据身高重建队列
局部最优可以推出全局最优。思路:输入:people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]] 输出:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]如果ratings[i] > ratings[i - 1] 那么[i]的糖一定要比[i - 1]的糖多一个,所以贪心:candyVec[i] = candyVec[i - 1] + 1。局部最优:当前累加rest[i]的和curSum一旦小于0,起始位置至少要是i+1,因为从i之前开始一定不行。
2025-03-27 19:44:00
866
原创 代码随想录算法训练营第二十八天 | 122.买卖股票的最佳时机II 55.跳跃游戏 45.跳跃游戏II 1005.K次取反后最大化的数组和
假如第 0 天买入,第 3 天卖出,那么利润为:prices[3] - prices[0],相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。贪心的思路,局部最优:当前可移动距离尽可能多走,如果还没到终点,步数再加一。局部最优:只找数值最小的正整数进行反转,当前数值和可以达到最大(例如正整数数组{5, 3, 1},反转1 得到-1 比 反转5得到的-5 大多了),全局最优:整个数组和达到最大。
2025-03-26 14:43:40
601
原创 代码随想录算法训练营第二十七天 | 455.分发饼干 376.摆动序列 53.最大子序列和
在计算是否有峰值的时候,大家知道遍历的下标 i ,计算 prediff(nums[i] - nums[i-1]) 和 curdiff(nums[i+1] - nums[i]),如果prediff < 0 && curdiff > 0 或者 prediff > 0 && curdiff < 0 此时就有波动就需要统计。输入: [-2,1,-3,4,-1,2,1,-5,4] 输出: 6,连续子数组[4,-1,2,1] 的和最大,为 6。视频讲解:。视频讲解:。
2025-03-25 09:39:53
672
原创 代码随想录算法训练营第二十五天 | 491.递增子序列 46.全排列 47.全排列II
输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]]输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]输入:nums = [1,1,2] 输出:[[1,1,2], [1,2,1], [2,1,1]]used数组,记录此时path里都有哪些元素使用了,一个排列里一个元素只能使用一次。
2025-03-23 19:14:43
369
原创 代码随想录算法训练营第二十四天 | 93.复原IP地址 78.子集 90.子集II
输入: nums = [1,2,3] 输出: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]递归调用时,下一层递归的startIndex要从i+2开始(因为需要在字符串中加入了分隔符.),同时记录分割符的数量pointNum 要 +1。时间复杂度: O(3^4),IP地址最多包含4个数字,每个数字最多有3种可能的分割方式,则搜索树的最大深度为4,每个节点最多有3个子节点。求取子集问题,不需要任何剪枝,子集就是要遍历整棵树。
2025-03-22 17:13:54
386
原创 代码随想录算法训练营第二十三天 | 39.组合总和 40.组合总和II 131.分隔回文串
如果candidates[i] == candidates[i - 1] 并且 used[i - 1] == false,就说明:前一个树枝,使用了candidates[i - 1],也就是说同一树层使用过candidates[i - 1],for循环里就应该做continue的操作。思路:输入: candidates = [2,5,2,1,2], target = 5, 输出:[[1,2,2],[5]]切割过的位置,不能重复切割,所以,backtracking(s, i + 1);
2025-03-21 21:56:39
703
原创 代码随想录算法训练营第二十二天 | 77.组合 216.组合总和III 17.电话号码的字母组合
叶子节点就是要收集的结果集,终止条件就是index 等于输入的数字个数(digits.size)了(本来index就是用来遍历digits的),然后收集结果,结束本层递归。第一次取1,集合变为2,3,4 ,因为k为2,我们只需要再取一个数就可以了,分别取2,3,4,得到集合[1,2] [1,3] [1,4],以此类推。还有一个参数就是int型的index记录遍历第几个数字了,用来遍历digits的,同时index也表示树的深度。这棵树,一开始集合是 1,2,3,4, 从左向右取数,取过的数,不再重复取。
2025-03-20 19:37:48
896
原创 代码随想录算法训练营第二十一天 | 669.修剪二叉搜索树 108.将有序数组转换为二叉搜索树 538.把二叉搜索树转换为累加树
将下一层处理完左子树的结果赋给root->left,处理完右子树的结果赋给root->right,最后返回root节点。如果root(当前节点)的元素小于low,那么应该递归右子树,并返回右子树符合条件的头结点;接着划分区间,root的左孩子接住下一层左区间的构造节点,右孩子接住下一层右区间构造的节点。要定义一个全局变量pre,用来保存cur节点的前一个节点的数值,定义为int型就可以了。定义的是左闭右闭的区间,所以当区间 left > right的时候,就是空节点了。视频讲解:。
2025-03-18 17:32:22
387
原创 代码随想录算法训练营第二十天 | 235.二叉搜索树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点
cur节点在区间(p->val <= cur->val && cur->val <= q->val)或者 (q->val <= cur->val && cur->val <= p->val)中,那么cur就是最近公共祖先了,直接返回cur。第五种情况:左右孩子节点都不为空,则将删除节点的左子树头结点(左孩子)放到删除节点的右子树的最左面节点的左孩子上,返回删除节点右孩子为新的根节点。第四种情况:删除节点的右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点。450.删除二叉搜索树中的节点。
2025-03-17 19:38:43
362
原创 代码随想录算法训练营第十八天 | 530.二叉树搜索树的最小绝对差 501.二叉搜索树中的众数 98.二叉树的最近公共祖先
判断一个节点是节点q和节点p的公共祖先:如果递归遍历遇到q,就将q返回,遇到p 就将p返回,那么如果左右子树的返回值都不为空,说明此时的中节点,一定是q 和p 的最近祖先。2.在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。我们要返回最近公共节点,返回值是TreeNode * ,如果遇到p或者q,就把q或者p返回,返回值不为空,就说明找到了q或者p。遇到空的话,因为树都是空了,所以返回空;
2025-03-16 16:43:08
552
原创 代码随想录算法训练营第十七天 | 654.最大二叉树 617.合并二叉树 700.二叉搜索树中的搜索 98.验证二叉搜索树
两个树遍历的节点t1 和 t2,如果t1 == NULL 了,两个树合并就应该是 t2 了(如果t2也为NULL也无所谓,合并之后就是NULL),反过来如果t2 == NULL,那么两个数合并就是t1。法三:设置一个节点pre保存中序遍历前一个节点,二叉搜索树按中序遍历:左<中<右,当前节点值<=前一个节点值,不是二叉搜索树;参数传入的是存放元素的数组,返回该数组构造的二叉树的头结点,返回类型是指向节点的指针。递归函数的参数传入的是根节点和要搜索的数值,返回的就是搜索数值所在的节点。
2025-03-15 10:24:47
435
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人