自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 【代码随想录算法训练营总结】

坚持就是胜利,虽然中间各种原因小断了几天(还差点因为阑尾炎寄了XD),但是还是顺利完结了。感觉一刷只能说是对各个算法有了大概的印象,马上第二遍再用C++刷一遍加深印象吧,加油。

2024-07-15 11:59:15 107

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

在这题使用欧氏距离最合适,总距离是点距离原点的欧氏距离加上到目标点的欧氏距离。本质上是因为dp[i][k][k-1]这些中间量还可能是由k更小的时候的组合推断出来的,所以对于所有的i和j,k都应该是从小到大递增推导所有i和j的状态,所以k在最外层。之前的题目都是只有一个出发点和到达点,这道题是有多个起始对,用之前的算法把每一对结果算出来也是可行的,在这里使用Floyd算法。本质上是一种动态规划,dp数组dp[i][j][k]中的i,j两点在以(1~k)中的点作为中间结点的时候的最小距离,递推公式是。

2024-07-13 14:20:10 235

原创 【代码随想录算法训练营第六十五天|卡码网94.城市间货物运输I&II&III】

限制经过K个城市那就是限制最多k+1条边,Bellman_ford算法松弛k+1次即可。还有一个要注意的是,正常B_F松弛在同一组松弛的时候,前一个松弛的边是可能对后续的边产生影响的,正常B_F是无所谓因为可以超过n-1次也不影响,但是在这里就需要注意,用来判断是否要更新距离是用上一次松弛完的结果来判断,但是松弛结果更新在这一次的结果中。在bellman_ford的基础上,在每次松弛的时候,只有和前面的结点相连的边的松弛才是有效的,因此可以引入一个队列存储已经访问过的结点,针对连接这些结点的边进行松弛。

2024-07-12 10:59:47 267

原创 【代码随想录算法训练营第六十四天|卡码网47.参加科学大会、94.城市间货物运输I】

Bellman_ford也好理解,就是每次对所有可以连接到的点(即对所有边)都更新一次距离原点的距离,每更新一次就能推断出距离原点+1结点位置的最近距离,那对于n个结点最多需要n-1次更新退出最近的距离。其实和昨天的方法差不多,一个是用邻接列表来表示点之间的连接,一个是用小顶堆的方式来存储边的权值,在找最短边的时候不用再去比较。

2024-07-11 11:20:10 210

原创 【代码随想录算法训练营第六十三天|卡码网117.软件构造、47.参加科学大会】

本体考察的是拓扑排序的思路,对于所有的有向无环图进行拓扑排序后输出的长度一定是和原结点数相同的。整体思路是找到当前所有的入度为0的结点,添加到结果中,并且查看对应的后续结点将其入度减1,如果减完之后入度为0,那就也添加到待处理结点中,直到找不到符合条件的待处理结点。最后查看结果长度与结点数是否一致,一致的话输出,不一致说明无法满足条件。本题使用的是dijkstra算法,和prim基本一致,唯一不同的是minDist数组中存放的不是到每个结点到已经访问结点的最小距离,而是距离源点的最小距离,别的都是一致的。

2024-07-10 10:44:05 313

原创 【代码随想录算法训练营第六十二天|卡码网53.寻宝(prim算法和kruskal算法)】

kruskal算法以边为导向,先把边按照长度从小到大排序,然后一个个检查边的两个端点是否在同一个集合中(这里使用并查集判断),在同一个集合中就不加入这个边,不在的话就加入。可以把所有已经使用过的结点看作一个整体,然后把他们相接的结点的结点顶点边中进行选择,选择最短的一条边把该结点入树,某种程度来说也是一种贪心?1.选择当前最短入树结点;3.更新结点距离最小生成树的距离。

2024-07-09 14:56:12 500

原创 【代码随想录算法训练营第六十二天|卡码网108.冗余连接、109.冗余连接II】

这一题则会有两种情况,第一种是出现一个结点有两个入度,这是题目所不允许出现的情况,还有一种就是和上题一样入度都为1但是出现了环的情况。因此在输入边的时候需要对每一个结点的入度进行统计,所有边输入进来之后,对所有边的入的结点判断是否入度为2,是的话则把这个边拿出来。如果有一个结点入度为2,那么就一定是在这两个入的边中挑一条删除,然后看剩下的结点中是否还会出现环,如果还出现环说明删错了,应该删除另一个;就是对输入进来的边判断是否在一个并查集中,在的话就把这个删除了,不再就加入并查集中。

2024-07-08 12:20:55 279

原创 【代码随想录算法训练营第六十天|并查集、卡码网107.寻找可能存在的路径】

纯并查集的基础应用,并查集只是看元素是否在同一个集合中,因此在加入的时候需要先查看两个元素是否已经在一个并查集中,如果不在再加入。并查集基础内容还是看代码随想录。

2024-07-06 20:07:47 254

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

在计算完所有岛屿面积后做出一个岛屿标号和面积的字典,然后遍历所有的位置,如果是海洋,则在他四周找岛屿,没找到一个不同标号的岛屿就加到结果中,最后选最大的一个岛屿面积和。可以把最外围的都检查一遍是否有为1的,有的话就把他接壤的全变成海,然后正常算面积。对第一边界和第二边界的格子往回推导,退出哪些格子能够流到第一边界和第二边界,如果一个格子能流到第一边界,并且可以流到第二边界那就输出他。这题就是从外圈找,找到未访问且为1的就把接壤的在新的岛屿图上标注为1。

2024-07-05 15:48:36 390

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

这题是在字符串上进行广搜,字符串广搜是对一个字符串按照位置来搜索,与原字符串只有一个位置字符不同那么就是在原字符串的基础上距离加1。因此需要一个字典来记录每个字符串和beginStr的距离,然后创建一个队列,每次对队列第一个字符串进行广搜,找到匹配且没有访问过的字符串就加入队列尾部等待处理,并且在字典中令他的距离变成现在访问的字符串的距离+1,直到遇见和endStr匹配的字符串输出距离。DFS去从1开始深度搜索,搜索到的结点标注,最后如果所有结点都标注了就输出1否则为-1。

2024-07-05 15:14:31 473

原创 【代码随想录算法训练营第五十七天|卡码网99. 岛屿数量、100.岛屿的最大面积】

创建一个同样大小的列表记录每一个区域是否被访问过,对于每一位置遍历,如果遇到了1并且没有访问过那就岛屿数量+1,然后把该区域的访问设置为True,然后用dfs去把这个位置接壤的为1的区域全都设置为已经访问过,这样之后遍历遇到就不会再计算入内。只需要把DFS改成DFS,在遍历到岛屿区域后对该位置进行BFS,在这区域的上下左右,如果一个区域没有被访问过且为1那么就设定该位置为访问过并且加入都队列中,直到队列为空。和上一题基本一致,在BFS/DFS的时候记录一下面积,最后选最大的面积输出。

2024-07-04 13:57:03 396

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

深度优先某种程度上和回溯真的一模一样,先进行终止条件判断,然后进入当前结点的遍历,满足条件进行操作后进入下一步的递归,最后回溯。BFS和DFS的具体理论就看代码随想录了。

2024-07-02 11:51:19 204

原创 【代码随想录算法训练营第五十五天|742.接雨水、84.柱状图中最大的矩形】

用单调栈来保存遍历过的木板,保持栈底到栈头从大到小的顺序,如果新的木板大于栈头的木板,则出栈,该木板决定了现在这个木桶的桶底的高度,然后还需要再判断一次栈是否为空,只有不为空的时候才能再取到左木板,使用这三块木板算出当前桶的存水量。其实感觉和双指针关系不大(如果是优化前的版本确实是双指针),因为每一个木块位置能存放的水的数量取决于他所处位置的水平线,水平线则是由它的向左找到的最大值和向右找到的最大值中的短板,拿水平线减去木板高度就是这个位置能找到的最大储水。

2024-07-01 16:32:00 241

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

因为这里需要的是每个数组元素右边第一个比他大的元素的间隔,因此单调栈是用来在遍历数组的时候存放还没有找到比他大的元素的下标,如果当前的元素比栈顶的元素大,那么就在结果对应的下标的位置记录下这个间隔,并且把该栈顶元素出栈,否则就入栈,等待后续的第一个比他大的元素出现。先和上面一样正常的向右找最近的更大元素,然后全部遍历完之后,再根据还在单调栈中(这些就是在右边没有找到下一个更大元素的元素)的最大索引,也就是栈顶的元素在nums中再从左往右和栈顶的索引对应元素对比一次大小。

2024-06-29 21:21:21 554

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

和上一题动规思路查不太多。初始化的时候把单个字符的回文长度初始化,然后如果再遇到两个字符相同的就直接在内部最长回文子序列的基础上+2,如果不相等就在分别扔掉这两个字符的情况下找最大值。j或者j=i+1,那么就是回文串,否则还要看这中间的是否是回文串,中间的是否是回文串就要看dp[i+1][j-1]这个是否为True,因此递归的顺序应该是i从大到小,j从小到大。dp[i][j]指的是s[i:j+1]这段是否是回文串,如果s[i]

2024-06-28 10:53:11 216

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

还有一个重要的是初始dp的时候需要对所有一个为空另一个不为空的时候的dp赋予初值,初值就是那个字符串的长度。项中s中出现过的t的次数,递推公式中当选择到s的第i-1的元素和t[j-1]相等时,需要考虑两种情况,第一种是选择用s[i-1]这个元素和t[j-1]匹配,那么dp[i][j]就应该是dp[i-1][j-1],如果不使用s[i-1]的话,就应该是和dp[i-1][j]相同,因此。当s[i-1]不等于t[j-1]时,就相当于是不使用s[i-1]和t[:j]匹配的情况,因此赋值为dp[i-1][j]。

2024-06-27 17:36:09 282

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

dp数组表示前i位数组的最大子数组和,dp[i-1]+nums[i]表示的是前面连续的最大数组和加上该位的值,与这个相比较的是nums[i],因为如果dp[i-1]为负数则需要丢弃前面的部分,从nums[i]重新开始计算。和上面也基本一致,就是最后统计一下最大公共子序列长度和s的长度是否一致,还有一个就是在两个元素不相等的时候,dp[i][j]的值取的是在同一个s的元素下,去匹配的上一个t的子字符串的dp值。和最长连续子序列的区别是,除了在。

2024-06-27 14:55:12 180

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

dp数组是i位的时候最长的连续递增序列的长度,相当于是对数组中每一个连续递增的子序列的长度都在对应位置上标记出来,最后返回的是dp数组中的最大值。dp数组是前i个元素所能构成的最长递增子序列的长度,dp数组初始都为1,对于每一个元素i,需要拿。这两个子数组中的最长重复子数组的长度,因为需要的是连续的重复子数组,所以每次都是比较。的基础上+1,最后取dp数组的最大值输出。两个是否相同,如果这两个相同的话就让。和他前面的所有元素进行对比,如果。dp数组是一个二维的数组,

2024-06-27 12:35:38 192

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

和前几个一样,dp数组变大到[n][2k+1],推导公式也一样。dp中多一个冷静期,别的还是一样的。

2024-06-26 10:26:20 149

原创 【代码随想录算法训练营第四十六天|121.买卖股票的最佳时机I&II&III】

dp数组的n*2的,dp[i][0]表示第i天持有股票的受益,dp[i][1]表示第i天不持有股票的受益。dp[i][0]在dp[i-1][0]和-prices[i]中取最大值(实际上就是要么之前就已经买了股票,要么是今天开始买,这里面找一个花钱最少的)。不持有股票的受益要么是继承昨天的受益,要么是昨天持有股票的受益+今天卖出股票的价格。局部最优是拿当前值和前面的最小值做差获得最大值,全局最优则是通过每个局部最优中取最大值。在之前的基础上多两个第二次买入卖出的状态,别的差不多。

2024-06-25 17:37:42 226

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

dp数组在这里是抢前i个房屋的最大受益,初始化头两个dp,推导的时候从前往后推,在前一位dp和前两位dp+现在的房子的受益中找最大值。然后对于每一个结点的子结点进入递归,如果偷这个结点那么返回的最大价值是结点价值+子结点不偷情况的最大价值,如果不偷这个结点则是可以在子结点的偷与不偷情况中选择最大的价值相加返回。树形的dp,每次递归返回一个两位的数组,第一位表示偷这个结点的当前最大价值,第二位表示不偷这个节点的当前最大价值,如果结点为None就返回[0,0]。

2024-06-21 10:27:54 147

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

零钱看作是物品,和为背包,最少的硬币数量就是在dp[i-coin]+1 和dp[i]中找最小值,所以初始dp赋值为inf,dp[0]另外设置为0。dp数组为字符串中每一位是否能够被拆分,然后对于每一位去和单词做匹配,如果匹配的上并且前面对应的位置位True,则令这个位置也为True。把小于等于n的完全平方数看作是物品,n是背包,其余和上一题一样。

2024-06-20 20:29:34 272

原创 【代码随想录算法训练营第四十三天|卡码网52.携带研究材料、18.零钱兑换II、377.组合总和Ⅳ、卡码网57.爬楼梯】

这题是完全背包问题,完全背包问题在01背包问题的基础上其实主要是三个不同,第一个是初始化的时候不能再和01背包一样对第一个物品让背包大小大于物品重量的时候全部初始化为物品价值,因为现在的物品可以无限放。第二个就是动态规划内部的循环推导的时候不用倒序而是正序了,因为之前提过正序会导致物品的重复使用,而现在正好是要重复使用。还有一个就是内外循环现在是可以交换的,只要保证dp前面的状态先于后面的状态计算出来就可以。其实这一题实际上要求的是排列,也就是上一题提到的背包在外的循环方式。

2024-06-19 10:36:13 402

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

先把每个字母的1和0的个数求出来,然后创建一个(m+1)*(n+1)的dp数组,第一个维度表示0的个数,第二个维度表示1的个数。然后对每个物体进行遍历,再对m和n倒序遍历,寻找dp[i][j]和dp[i-num[0]][j-num[1]]+1中的最大值。的时候都不可能实现,返回0。这里dp[i]数组表示的是和为i时的可能路径数,初始dp[0]可以看作是和为0且没有数字可以选择的时候,初始化为1,路径数是dp[i]已经有的路径加上选择数字num时的dp[i-num]的路径数。

2024-06-18 12:16:59 289

原创 【代码随想录算法训练营第四十天|卡码网46.携带研究材料,416.分割等和子集】

但是这样就必须要先物品后背包(不然一直都是同一个物品(物品1)在遍历),然后在遍历背包的时候还要注意只能倒序遍历,如果正序的化,前面的数据如果已经添加了该物品,则会重复添加(因为二维dp的时候用的时上一层的数据,不会出现覆盖而重复添加)。dp数组[i][j]前一位表示的是物品的种类,后一位表示的是背包的容量,在物体为i时,容量为j的背包的最大价值由不放入i的。中的最大值所决定,当然这是在容量大于spaces[i]时才能实现,小于spaces[i]的时候则只能维持。所以如果数组总和为奇数直接返回False。

2024-06-17 19:52:11 275

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

dp内容是值为i的时候的二叉搜索树的可能个数,值为i时,他可能的二叉搜索树是从1到i的所有元素作为根节点的树相加的,对于每一个作为根节点的元素j,他的可能搜索二叉树由小于j的元素[j-1]的dp值构成左子树,由大于j的元素[i-j]的dp值构成右子树,则根节点为j的树的dp值为左右子树的dp值相乘。dp是每个各自的路径的和,每个格子的路径是左边格子和上边格子的和。这里初始化的时侯假设所有格子都只有一条路径,然后遍历所有格子,如果i-1和j-1大于0则可以把对应格子的值加上。

2024-06-15 14:47:22 347

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

dp数组定义为爬到对应楼层的最小花费, 楼层一共有len(cost)+1层,因为可以从0或者1层起始,所以dp[0]和dp[1]都是0,传递函数是前两层的dp加上对应的cost之后的最小值。这里不用递归的方法,用动态规划的dp数组来存储每个n的斐波那契数,然而最后只需要返回n的斐波那契数,所以只保存最近的两位斐波那契数就可以了。和斐波那契基本一样,n层的状态是n-1和n-2层的合,区别是只有n=1开始有意义,同样也可以只保留两个最后的状态。

2024-06-15 11:46:12 263

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

另一种从前往后,找到当前值大于后面值的就设置当前索引为flag,然后需要判断前值是否与当前值相等,一直要找到第一个相等的值的位置,让这个位置的值-1,并把flag设置在那个位置,然后把flag及后面的值都赋值为9.先按照右边界对数组排序,然后判断前一个区间的右边界是否大于该区间的左边界,大于的话就说明上一个区间的右边界在该区间内,两个区间有交集,因此把两个区间取成交集后再放回数组中,如果区间没有交集那就放到输出中。

2024-06-13 14:35:24 410

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

先把每一个位置上的字母计算出它出现的最远的位置,然后遍历字符串,设置左边界和右边界,如果字符串的最后出现位置大于现在的右边界,则把右边界重新设定为该位置,如果当前位置就是右边界,则把左右边界内的字符串就是一个分割,左边界重设为右边界+1。如果后一个气球的左边界小于等于上一个气球的右边界,那么就可以同时被一箭射爆,因此可以把这个气球和上一个气球看成新的个体,其右边界为两个气球的最小右边界,再去和下一个气球进行判断。

2024-06-13 10:33:00 207

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

把数组先排序,排序好后根据k和数组长度中最小的那个进行遍历,目的是如果有负数的就把他们从小到大依次取正,然后按照还剩下的k的数量来判断,如果是偶数则按照当前数组输出,如果是奇数则需要把当前数组的最小值取反再求和。第二次是从右往左,如果左边的分大于右边的,如果左边的糖果本来就大于右边的则不变,否则变成右边的+1。假设从0出发,保证每一次加完油跑到下一个站点时油量大于等于0,如果油量小于零了就把启示站移到下一个加油站,如果总的gas和小于cost的和那怎么都是不能跑完全程,返回-1。

2024-06-12 17:47:08 214

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

从前往后正推,每次走到当前的最大范围了就step+1,范围变成下一个最大范围。只需要遍历到倒数第二个元素,最后一次走到倒数第二个元素就不用判断是否走到了当前的最大范围了。我是从倒数第二位开始看,如果下标+可以跳跃的长度大于等于最后一位下标,则把它的下标看作新的目标,往前依此类推,最后看最小符合要求的下标是否为0。想了一个用回溯的方法做的,但是超时间限制了,但如果是要所有可能路径+step的话可以这样做。计算相邻两天的利润,如果是正的就加到结果里,负的就扔掉。还是从后往前倒推来做的一种方法。

2024-06-12 11:22:19 249

原创 【代码随想录算法训练营第三十一天|455.分发饼干、376. 摆动序列、53.最大子数组和】

如果相邻梯度相乘为负数,索引+1,否则把这个元素删除,最后剩下的元素个数如果大于2那就返回这个长度,如果只剩下两个元素则需要看是两个相等的元素还是不等的(至少会返回两个元素),相等返回1,否则是2。count用来计算连续数组的和,当count<0的时候就需要将前面的抛弃掉,否则就继续累加,最终返回最大的count。优先保证胃口最大的分到能满足要求的最大的饼干,所以要先对胃口和饼干排序,然后给胃口最大的喂能满足的最大的饼干。

2024-06-07 15:24:15 227

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

在回溯的时候,是查看每一个机场是否还有可以飞的机场,如果没有的话就说明他是目前的最后一个机场,把他添加到结果中,如果还有机场的话则把这个机场pop出列表,进入递归。因此结果中的机场的添加顺序和最终返回的顺序是相反的,因此在做机场的配对的字典的时候需要根据字母的顺序反向排序机场,这样在输出的时候再一反序就是需要的答案。出发机场和到达机场之间的关系就是一组键值对,因此先用一个字典创建出每个机场可能到达的机场的键值对,每个机场对应一个可以到达的机场的列表。

2024-06-07 13:30:12 234

原创 【代码随想录算法训练营第二十九天491.非递减子序列、46.全排列、47.全排列II】

和上一题相比,需要对给定的数组先排序,然后根据相邻位置的是否相等来判断有没有在这一层使用过这个数,如果相等并且pre为False说明在这一层已经使用过了,直接跳过,别的一样的。因为给的数字中元素不会重复,所以再做一个数组存放每个元素使用过的信息,如果没使用过就添加到path,最后path和原数组长度一致的时候添加到ans里。因为给的数组的顺序是不确定的,所以在每一次的递归中都要用一个集合来存放本层使用过的数字,后面出现同样的数字就跳过。

2024-06-05 10:56:58 309

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

主体部分是做一个循环,因为ip每一位最多三个数字,所以可以取1~3个字符出来,取出来之后做判断这个数是否符合要求,如果是0则直接跳过取别的数目的字符,直接进入下一步的递归,索引+1,ip位置也加一,如果数字大于255则跳过这个可能。回溯的条件是ip位置大于3,或者索引大于等于字符串的长度,在索引等于字符串长度并且ip位置刚好为3的时候把这个ip添加到输出结果中。回溯函数有四个参数,第一个是字符串,第二个是目前在字符串中的索引开头位置,第三个是目前的ip位置,第四个是已经放入ip的字符串。

2024-06-04 11:15:51 189

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

不知道说啥,但总得写点什么吧。和上一题相比排序去重一下就行。

2024-06-03 14:48:00 182

原创 【代码随想录算法训练营第二十五天|回溯算法:216.组合总和 III、17. 电话号码的字母组合】

和给的代码写的不大一样,但思路基本一致。怎么感觉回溯的套路都一样的。

2024-06-03 13:31:51 192

原创 【代码随想录算法训练营第二十四天|回溯算法:77.组合】

记住回溯算法的模板还是很好写出来的。

2024-05-31 15:43:46 156

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

迭代的比较麻烦,一开始要对根节点额外处理(因为根节点没有前置结点),如果根节点数值大于左边界则直接取右结点(左子树的值一定都小于根节点),大于右边界同理。然后再从移动后的根节点开始,对根节点的左右子树做删减,如果左结点值小于左边界,直接指向左结点的右子树,并且一直向左下角迭代,直到最左下角的值也大于左边界,右结点同理。返回条件有三个,当走到None的时候直接返回,如果结点的值小于左边界,则返回结点的右结点,但是右结点也可能有小于左边界的值,因此实际返回的是进入递归修剪后的右子树;

2024-05-30 11:37:45 146

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

在普通二叉树的最近公共祖先的基础上,现在知道了二叉树的大小顺序,可以拿当前结点的值和目标比较,如果一大一小则当前结点就是最近公共祖先,如果同时大或同时小则要让右结点或左结点进入递归寻找。5:结点存在,且左右子树存在,可以对右子树遍历左端,将左子树放置于右子树的最左下端(因为左子树的所有值均小于右子树的最小值),再用右子树的根节点替换原结点。3:结点存在,并且右子树存在,左子树不存在,直接用右子树的根节点代替原结点。4:结点存在,并且左子树存在,右子树不存在,直接用左子树的根节点代替原结点。

2024-05-29 12:31:09 190

空空如也

空空如也

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

TA关注的人

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