自定义博客皮肤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)
  • 收藏
  • 关注

原创 代码随想录训练营总结篇

是的我就是那个第一题都做不出来的人,我是跨考生只会一点点C,第一次见到两数之和的C语言哈希表解法时大为震撼。太复杂了,于是在刚开始刷题的那几天,我一边用C完成每天的任务一边上C++语法基础课。这时候如果能有一个过来人来传授经验,那么可以少走很多弯路,我认为随想录扮演的就是这种过来人的角色。我认为能把别人教会是一件非常厉害的事情,我大概在45天左右就完成了随想录的所有题目,包括图论和拓展题目。诚然,现在的我依然是个菜狗,但相较于两个月之前的自己,在算法上算是有了一些进步,这已足够让我高兴。

2024-02-29 23:56:55 446

原创 代码随想录训练营第六十四天打卡|84.柱状图中最大的矩形

遍历到6这个柱子时,左边7比它高,那我们就直接跳到第一个比7矮的柱子5这就是目标柱子,记录下标就行。遍历到最后一个柱子5时,左边柱子6比它高,那我们就直接跳到第一个比6矮的柱子5,5>=5,所以我们继续跳到4找到目标柱子返回下标。求取面积的过程中,要找到以该根柱子作高,勾勒出矩形的宽。所以要找到左右第一个比该柱子矮的柱子的下标,这就是leftMinIndex,rightMinIndex两个数组的作用。单调栈的核心在于while循环,虽然之前的元素出栈了,但由于保存的是下标,达到了一种“音容宛在”的效果。

2024-02-28 16:30:46 390

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

知名hard题,自己想挑战一下,缝缝补补写了一个多小时依然只能通过四分之一左右的测试用例,遂放弃。相比于之前的单调栈,多了循环数组的处理,很高兴一下子就想到了最简洁的写法。1.暴力法,和每日温度那一题如出一辙,循环数组用了一个取模运算就解决了。2.单调栈,简洁写法。本题单调栈是按照行方向来计算雨水,这句话很关键。本题的双指针解法其实还挺容易理解的。(注释版)理解了逻辑,代码并不复杂。

2024-02-27 23:58:38 446

原创 代码随想录训练营第六十二天打卡| 739. 每日温度 496.下一个更大元素 I

本题虽然是easy,但是单调栈法却比上一题复杂,需要多用一个map哈希表记录映射关系,反而是暴力法比较容易想到且写出代码。不过本质单调栈的思想并不难理解。1.暴力法,两层for循环。第一次最后一个测试用例没过,稍微优化了一下。虽然过了,但是时间开销较大。在数组2中找到目标元素,然后往后遍历找到第一个比目标元素大的元素。个人感觉不难理解,关键在while循环,有点像之前的单调队列?今日总结:单调栈,启动!

2024-02-26 22:34:42 415

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

1.动规,布尔类型的dp[i][j]:表示区间范围[i,j] (注意是左闭右闭)的子串是否是回文子串,如果是dp[i][j]为true,否则为false。例如本题情况三:下标:i 与 j相差大于1的时候,例如cabac,此时s[i]与s[j]已经相同了,我们看i到j区间是不是回文子串就看aba是不是回文就可以了,那么aba的区间就是 i+1 与 j-1区间,这个区间是不是回文就看dp[i + 1][j - 1]是否为true。一个元素可以作为中心点,两个元素也可以作为中心点。2.动规,不初始化单个字符。

2024-02-24 21:34:39 501

原创 代码随想录训练营第五十九天打卡|583. 两个字符串的删除操作 72. 编辑距离

2.动规,直接求删除次数。dp[i][j]:以i-1为结尾的字符串word1,和以j-1位结尾的字符串word2,想要达到相等,所需要删除元素的最少次数。关于递推数组简化部分我觉得随想录的解释还是有点问题,我觉得不是很好理解。基本相同,只要求出两个字符串的最长公共子序列长度即可,那么除了最长公共子序列之外的字符都是必须删除的,最后用两个字符串的总长度减去两个最长公共子序列的长度就是删除的最少步数。有了之前的铺垫,这一题就显得不那么难了,注意。(详细讲解还是看随想录录吧)今日总结:编辑距离。

2024-02-23 23:23:39 374

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

当s[i - 1] 与 t[j - 1]不相等时,dp[i][j]只有一部分组成,不用s[i - 1]来匹配(就是模拟在s中删除这个元素),即:dp[i - 1][j]所以递推公式为:dp[i][j] = dp[i - 1][j];= t[j - 1]),此时相当于t要删除元素,t如果把当前元素t[j - 1]删除,那么dp[i][j] 的数值就是 看s[i - 1]与 t[j - 2]的比较结果了,即:dp[i][j] = dp[i][j - 1];1.动规,二维数组版。

2024-02-22 14:59:15 1056

原创 代码随想录训练营第五十七天打卡|1143.最长公共子序列 1035.不相交的线 53. 最大子序和

如果dp[i - 1] >0那么nums[i]应该加入当前连续子序列和,dp[i]=dp[i-1]+nums[i],如果dp[i - 1] <0,那我们应该从头开始计算当前连续子序列和,即dp[i]=nums[i]。dp[i][j]:长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列为dp[i][j],之前说过这种定义方式及递推公式在子序列和子数组问题中经常出现。1.之前我们用贪心解决过该问题,现在我们用动规的方法再来解决该题目一次。

2024-02-21 23:23:47 358

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

考虑一个简单的贪心,如果我们要使上升子序列尽可能的长,则我们需要让序列上升得尽可能慢,因此我们希望每次在上升子序列最后加上的那个数尽可能的小。: “以下标i - 1为结尾的A” 标明一定是 以A[i-1]为结尾的字符串 )。其实定义dp[i][j]为 以下标i为结尾的A,和以下标j 为结尾的B,最长重复子数组长度也是可以的,只不过代码稍微麻烦一点,有兴趣的同学可以看随想录本节的拓展部分。dp[i][j] :以下标i - 1为结尾的A,和以下标j - 1为结尾的B,最长重复子数组长度为dp[i][j]。

2024-02-20 23:56:07 373

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

可以见到的是状态2的转移方程变成了dp[i][1] = max(dp[i - 1][1], dp[i - 1][2]);这样代码也是能AC的,这是我无意中写出的,引发了我的疑问。(状态二)即:dp[i][1],有两个具体操作:操作一:前一天就是状态二,操作二:前一天是冷冻期(状态四)dp[i][1] = max(dp[i - 1][1], dp[i - 1][3]);(状态二)即:dp[i][1],有两个具体操作:操作一:前一天就是状态二,操作二:前一天是卖出股票(状态三),即今天是冷冻期。

2024-02-19 21:51:05 382

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

1第一次持有股票,2第一次不持有股票,3第二次持有股票,4第二次不持有股票。dp[i][j]中 i表示第i天,j为 [0 - 4] 五个状态,dp[i][j]表示第i天状态j所剩最大现金。我在122.买卖股票的最佳时机II中曾吐槽过状态转移方程,觉得太麻烦,但是到本题就发现统一状态转移方程写法的好处了。模仿123.买卖股票的最佳时机III 的思路AC了,印象中是第一个没看题解AC的困难题。3.交易次数优化,一共只有n天,最多交易n/2次,当天交易没有意义。今日总结:继续炒股。

2024-02-18 18:45:33 347

原创 代码随想录训练营第五十三天打卡|121. 买卖股票的最佳时机 122.买卖股票的最佳时机II

其实一开始现金是0,那么加入第i天买入股票现金就是 -prices[i], 这是一个负数。dp[i][1] 表示第i天不持有股票所得最多现金。(一开始我觉得随想录这样写是不是把简单问题搞复杂了,到后来才发现这样的写法在该系列题目中更通用)2.滚动数组版(只需要记录当前天的dp状态和前一天的dp状态就可以了)贪心:取最左最小值,取最右最大值,那么得到的差值就是最大利润。动态规划:dp[i][0] 表示第i天持有股票所得最多现金 ,3.自己写的动规,感觉还是贪心的思想,只不过套了动规的模板。

2024-02-17 12:51:30 310

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

如果上天给我一次重来的机会,我选择不偷第一家,这样我就可以偷最后一家了,虽然不一定偷最后一家。考虑以上两种方案代表的是可以偷第一家和不可以偷第一家,或者说是不可以偷最后一家和可以偷最后一家,因此可以包含所有情况。(如果对重复计算不理解可参考这句话:我们计算了root的四个孙子(左右孩子的孩子)为头结点的子树的情况,又计算了root的左右孩子为头结点的子树的情况,计算左右孩子的时候其实又把孙子计算了一遍。dp[i]的值不一定是偷了下标为i的那一家,只是这一家能偷,如果不偷这一家能带来更高的收益,那就不偷。

2024-02-16 11:51:51 390

原创 代码随想录训练营第五十一天打卡|139.单词拆分

还有就是本题一定是先背包再物品,还记得之前说过先背包再物品求的是排列。注意到题目中说字典中的每个单词可以重复使用,本题单词就相当于物品。先背包再物品求排列这个过程中对于不同容量的背包都会把所有的单词都遍历了一遍,就相当于重复使用了单词。而如果先物品再背包,我们会发现对于每个单词我们只使用了一次,之后不再进行重复遍历从而达不到重复使用单词最终结果错误。因为我们在回溯的过程中做了大量的重复工作,所以我们可以把之前的结果进行标记。再遇到相同的情况,我们直接把之前的结果拿来用。今日总结:单词拆分。

2024-02-15 14:16:22 367

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

因为此时的背包是总金额必须比当前的硬币面值大,否则将没有意义,dp数组下标也不可能为负数。例如设成INT_MAX-1就行,因为dp数组是取较小值,而更新部分最多+1,一定不会发生整型溢出。因为求取的是最少硬币数量,dp数组除了dp[0]初始化为0,其它部分都初始为最大值INT_MAX。两层for循环决定求的是组合数还是排列数,如果外层循环遍历物品,内层循环遍历背包则求的是组合数。而本题求的是最少硬币个数,先背包再物品或先物品再背包都是OK的。3.先背包再物品,背包从0开始或者从1开始都是可以的。

2024-02-14 20:05:34 448

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

这样最后的收集结果还会正确吗?事实上答案就是符合范围的,但是不是答案的dp数组元素可能会发生溢出,且发生溢出的dp数组元素不会出现在答案dp[target]的累加路径上(笑)。因为阶码部分表示的数比较大,尾数部分只有23位,当这个数不能被完全精确表示,float会转化成能表示的最接近的整数部分从而丢失精度。本题说是计算并返回可以凑成总金额的硬币组合数,例:{1,5}和{5,1}算作一种组合,而如果颠倒for循环的顺序,计算出来的就是排列数,{1,5}和{5,1}作为两种不同的排列都会被加入结果集。

2024-02-08 11:32:40 368

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

举个例子:目标和=加法总和+减法总和,如果目标和是奇数,那么加法总和和减法总和肯定一个是奇数一个是偶数,那么他们俩加起来只能是奇数,即目标和是奇数,总和也只能是奇数。如果目标和是偶数,那么加法总和和减法总和要不是奇奇,要不是偶偶,他们俩加起来一定是偶数,即目标和是偶数,总和也是偶数。递推公式:dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1),该递推公式给我们的启发是+1,状态转移时目标值只会+1,后面我们还会碰到一些题目是类似的思想。

2024-02-07 18:03:04 434

原创 代码随想录训练营第四十二天打卡|背包问题 416. 分割等和子集

如果数组元素之和为偶数,那我们就选择其之和的一半作为背包容量,寻找该背包能装载的最大物品重量(即子集之和)。在使用二维数组的时候,递推公式:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);所以递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);在一维dp数组中,dp[j]表示:容量为j的背包,所背的物品价值可以最大为dp[j]。

2024-02-06 13:16:58 421

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

对于每一个i,当 i≥2 时,假设对正整数 i拆分出的第一个正整数是 j(1≤j<i),则有以下两种方案:将 i拆分成 j 和 i−j 的和,且 i−j 不再拆分成多个正整数,此时的乘积是 j×(i−j);将 i 拆分成 j和 i−j 的和,且 i−j 继续拆分成多个正整数,此时的乘积是 j×dp[i - j]。j有多种取值,所以递推公式就变成了dp[i] = max(dp[i], j * max(i - j, dp[i - j]))。对于j*(i-j)拆成两个,前面一半和后面一半是对应的没有必要。

2024-02-05 12:43:23 376

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

(4)确定遍历顺序这里要看一下递推公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1],dp[i][j]都是从其上方和左方推导而来,那么从左到右一层一层遍历就可以了。3.一维数组空间优化版。(注意到dp[i][j] = dp[i][j - 1] + dp[i - 1][j]中dp[i - 1][j]状态可以拷贝到dp[i][j]上,那么状态转移方程可变为dp[i][j] = dp[i][j - 1] + dp[i][j],不再需要i即变为dp[i] += dp[i - 1])

2024-02-03 10:20:55 375

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

首先是dp[i - 1],上i-1层楼梯,有dp[i - 1]种方法,那么再一步跳一个台阶不就是dp[i]了么。还有就是dp[i - 2],上i-2层楼梯,有dp[i - 2]种方法,那么再一步跳两个台阶不就是dp[i]了么。dp[1] = 1。5.举例推导dp数组,如果代码写出来,发现结果不对,就把dp数组打印出来看看和我们推导的结果是否一致。dp数组通常是和我们的目标值联系起来的,本题要求的是斐波那契数列第n项的值。想要到达当前台阶,之前位置要不在当前台阶的上一个台阶,要不就在当前台阶的前两个台阶。

2024-02-02 10:42:00 360

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

例如:98,一旦出现s[i - 1] > s[i]的情况(非单调递增),首先想让st[i - 1]--,然后s[i]给为9,这样这个整数就是89,即小于98的最大的单调递增整数。从前向后遍历的话,遇到s[i - 1] > s[i]的情况,让s[i - 1]减一,但此时如果s[i - 1]减一了,可能又小于s[i - 2]。这么说有点抽象,举个例子,数字:332,从前向后遍历的话,那么就把变成了329,此时2又小于了第一位的3了,真正的结果应该是299。不出意外的超时了,只通过了三分之二的测试用例。

2024-02-01 10:33:12 363

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

模拟没通过测试用例的执行过程,原来是思路有问题,当前片段的最远边界不一定是当前片段首元素最后出现的位置。1.模仿射气球那一题的思路,把区间按左边界从小到大排序,遇到重叠区间就删除,同时更新区间右边界,保留最小的那个。之后遍历区间,如果能合并就和结果集最后一个元素合并,如果不能合并就把该区间加入结果集作为结果集新的最后一个元素。(我是废物版,对照题解修改了好几次才AC,就不注释了)2.按照区间右边界从小到大排序,统计非重叠区间个数,最后用区间总数减去非重叠区间个数就是需要删除的区间总数。

2024-01-31 17:41:30 407

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

对于10块钱找零只能使用5块钱,对于20块钱找零可以使用10块钱和5块钱或3个5块钱的组合。且优先使用10块钱和5块钱的组合找零20元,因为10块钱只能用于找零20元,而5块钱能用于10块钱和20块钱的找零,使用范围更广。(注:如果有10块钱的情况下找零失败了,说明没有5块钱了,那么全部用5块钱找零的方法也会失败,所以返回false是没问题的)身高相等的情况下按k升序排列,因为如果身高相等先插入k大的节点,那么后序插入身高相等k小的节点可能会影响之前已经插入的身高相等k大的节点。今日总结:公园综合活动。

2024-01-30 12:41:06 362

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

3.全局考虑法,情况1和2都比较容易理解,关键是如何理解情况3。所以只要从后往前填平漏洞就能找到起始位置,因为这时候就相当于找到了一个起始位置>=0的部分,且这部分之和>=0,且这部分之和与另一之和<=0的部分之和>=0。(>=0的那部分往后继续行驶的过程中不可能<0,否则就违背了与另一部分之和的和>=0这个条件)因为差值数组一定能分成连续的两部分,一部分之和>=0(这部分的开头必须>=0,保证能从这里起跑),另一部分之和<=0,且这两部分之和一定>=0,这时候>=0的那一部分的开头就是起始位置。

2024-01-29 13:47:26 403

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

1.其实本题的思路和之前是一样的,每次在能跳到的位置中选择能跳地最远的那个,那么最后的跳跃次数就是最小的那个。只不过本题相比于上一题的难度在于跳跃次数的统计,核心是每次跳到最远的那个位置跳跃次数+1,然后在当前位置能跳跃到的那个位置选择新的那个能跳的最远的位置。代码的逻辑应该是这样的:每次确定了起跳位置跳数+1,这也是i < nums.size() - 1的原因所在。本题我们一个朴素的思想就是如果当前位置跳不到最后位置,那我们就在当前位置能跳到的位置中选择能跳的最远的那个,这其实就是贪心!

2024-01-27 12:33:01 406

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

因为正负交替的逻辑是diffenence[j]*diffenence[j+1]<0,例如差值序列(2,-3,-2,4),-3乘以-2是>0的,不符合正负交替逻辑,所以我们后移。-2乘以4<0,是差值序列,所以我们最后得到的差值序列是(2,-3,4)这样也是符合要求的,因为这里面-3乘以-2>0我们后移差值序列-2和-3符号是相同的,所以4和-2异号等价于4和-3异号。这样-3就会认为后面都是和它同号的数了,于是得到差值序列(2,-3),但实际上的差值序列应该为(2,-3,4)。想一下,本题的贪心贪在哪里?

2024-01-26 12:56:46 391

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

顺序遍历出发机场到下一个机场的所有路径(顺序遍历是符合字典顺序的),找到路径就加入结果集同时该路径标记为0,表示飞过了,防止之后重新飞发生死循环。1.有了上题的经验,本人先是尝试独立AC,未果,遂看题解。该循环记录了初始一个机场到另一个机场的路径条数[vec[0]]对应出发机场,[vec[1]]对应到达机场。而且targets作为map结构是有排序功能的,比如A到B,C都有路径,记录结果也是先A->B再A->C,也就是说对于某一机场找下一个他可能到达的机场,我们只需要顺序的遍历它可能的路径就行。

2024-01-25 12:39:40 409

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

模拟代码的执行过程,我们发现第一层递归我们选择了1,第二层递归for循环的第一轮我们选择了第一个1,由于树枝去重的关系第一个1被跳过。(其实used[i - 1] == true也能达到去重效果,本质上是所有树枝去重达到对前一位的去重,效率不如直接对树层去重。举个例子,对于数组[1,2]的全组合只有一个[1,2]或[2,1],而它的全排列则有两个[1,2]和[2,1]。在组合问题中我们使用startIndex,每次递归时i+1,因为我们只需要找到一个[1,2]就行,2不用回头找1。

2024-01-24 12:18:37 917

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

因为之前的模板并不完全适用,甚至可以说只有回溯与切割的思路是适用的,其它的具体实现与之前有较大差异。而本题的结果集的字符串数组,意味着你的路径是字符串,而字符串是不好回溯的。这就要求我们转变思路,把字符串本身作为路径,合法切割在后面+'.',不合法把'.'删除重新切割,这种思路的转换对于字符串不熟悉的同学来说并不简单。本题是子集问题的进阶,数组中出现了重复元素,要求我们进行去重操作。去重要先进行排序,去重意味着在for循环中,之前某个元素开头的数组已经全部收集完了,之后再有相同元素开头直接跳过。

2024-01-23 12:21:45 316

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

本题属于组合的切割部分,要明确终止条件,相比于一般的组合问题多了个回文串判断条件。而暴力之处在于回文串判断函数采用的是双指针法,改进版是事先计算好字符串及子串是否是回文串,然后直接查询就好。本题和之前相比在于数字能多次使用了,递归时起始位置可以和当前i相同,不用+1了。因为题目中说了无重复元素的整数数组,每一个元素的情况在它那一层就已经处理完了,之后不会再重复。剪枝需要先将数组排序,当当前元素之和超过target时,这一层后面元素之和一定也超过target,所以可以提前结束for循环退出递归。

2024-01-22 12:06:31 410

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

2.这题我们还有一个更进一步的剪枝思路,因为我们循环时i是逐渐增大的。所以,当某一刻我们发现组合之和已经>n时,说明后面的组合之和也一定>n不满足条件了,就不用继续递归了,直接结束递归返回。1.有了昨天做77.组合的经验,这题也是一样的思路,无非是多了个判断条件组合总和是否=n。(for循环内已经做了初步剪枝)1.其实本题的回溯部分倒不是很难理解,反而是电话数字与字母之间的映射关系不容易想到。今日总结:她总是只留下电话号码~

2024-01-20 18:08:44 423

原创 代码随想录训练营第二十四天打卡| 77. 组合

剪枝的依据通常是递归终止条件,例如本题终止条件就是收集到k个元素的数组就加入到结果集,如果剩下的元素加起来都不到k个那后面的搜索是不是就不必要了?当前收集数组的元素个数是path.size()个,一共要收集k个,还需要收集k-path.size()个。i的范围是[1,n],要保证i(包括i)往后至少还有k-path.size()个,那么就要求i<=n-(k-path.size())+1。所以要保证i到n有k-path.size()个元素,只需要n-i=k-path.size()-1就行。

2024-01-19 12:24:53 320

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

于是我们就有了想法,从后往前遍历,也就是右中左,累加每个结点的元素值,再把累加值赋给当前遍历结点。也就是说如果左子树的根节点如果在范围内,则左子树的右子树一定在范围内,左子树的左子树可能在范围内。如果左子树的根节点不在范围内,则左子树的左子树一定不在范围内,左子树的右子树可能在范围内。根据这个逻辑依次往下判断,直至叶子结点,根节点的右子树同理。2.迭代法(迭代法的实现是借助3个辅助队列,一个放结点另两个放左右区间的下标,根据左右区间下标找到数组中间值赋值给结点,然后更新辅助队列,依次重复这个过程)

2024-01-18 12:23:22 364 1

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

苦思冥想半天才理解了,迭代的变量处理“继承”下来了,比如上一个if条件满足了理论上下一个if条件是不会满足了,但是上一个if条件满足后对一些变量做了修改,而这些变量作为下一个if条件的判断条件发生了变化就会导致部分情况下一个if条件也满足,从而导致结果错误。1.一个很朴素的思想就是新结点都是可以插在叶子结点后面的。知道了要插入结点对应的元素值,那我们就可以根据搜索二叉树的性质,大了向左小了向右一直找到要插入的叶子结点,再根据元素值大小与叶子结点对应的元素值大小选择插入该叶子结点的左边或右边。

2024-01-17 14:26:42 351

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

因为公共结点可能是一个结点本身,所以我优先处理了p是q的祖先和q是篇的祖先,进行了剪枝。逐层遍历二叉树,出现新的公共祖先结点就更新返回结点,最后更新的祖先节点一定是最近的公共祖先结点。2.在朴素思想中,我们没有用到二叉搜索树的特性,即它的中序遍历是一个单调的序列。有着相同元素值的结点一定是相邻的,那我们就可以在中序遍历的过程中记录最大频率对应的元素值。1.一个朴素思想就是遍历这个二叉树并记录每个元素出现的频率,再按照频率从大到小排序,输出频率最大的一个或多个元素值。(普适方法,所有的二叉树都能处理)

2024-01-16 17:09:54 365 1

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

区别在于之前是根据前序或后序数组找到根节点,再根据根节点在中序遍历数组中的位置将数组划分为左右两部分依次进行递归。而本题是找到最大值在数组中的位置,根据最大值位置将数组划分为左右两部分再依次进行递归,是少数一次就AC的题目。1.递归法(初始化初值),要利用搜索二叉树的特性,只能采用中序遍历,因为二叉搜索树的中序遍历是非递减序列。3.迭代法(就是套上中序遍历的迭代模板,在合适的位置上加入判断逻辑)2.递归的简洁写法(1,2都不空的时候用1接收合并值)2.迭代法(根据二叉搜索树的特性,迭代最简单的一集)

2024-01-15 12:41:40 379 1

原创 代码随想录训练营第十八天打卡| 找树左下角的值 路径总和 从中序与后序遍历序列构造二叉树

3.迭代法,前序遍历版(创建一个栈结构,栈内元素包含当前结点以及当前结点的路径之和,按前序遍历顺序出栈依次判断路径之和是否等于目标值)1.递归(注意路径不止一条,要想把递归中获得的路径全部加入,最好设置一个全局变量接收返回路径)1.递归(注意递归函数的返回类型,不同的返回类型需要不同的处理方式)2.迭代,层序遍历(找到最后一层第一个结点,返回其值)1.递归(找到第一个深度最大的叶子结点,返回其值)2.递归法精简版(注意回溯的实现)1.递归法(主要是数组的划分切割)1.递归法(还是划分数组)

2024-01-13 12:32:04 389 1

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

2.递归法精简版(隐藏着回溯,其实就是需要回溯的地方作为递归参数的一部分随着递归栈的弹出,回到了上一轮递归的状态,完成了回溯)1.第一反应是迭代法用层序遍历把每个结点都判断一次,但是二叉树的结点深度需要用一个函数实现,可以递归也可以迭代。2.递归写法(递归函数的关键在于理解递归函数的作用,也就是这个函数干了什么。3.迭代法(路径栈的栈顶保存的是当前路径,而不是单个的结点,以此完成回溯)厘清左子叶的定义就不难写了(判断条件牵扯到其父节点)1.递归法(第一次正经接触到回溯)今日总结:回溯溯溯溯溯溯溯溯……

2024-01-12 18:06:21 381 1

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

1.第一想法是迭代法层序遍历,深度最小的末尾结点一定是层序遍历第一个左右孩子都为空的结点。1.很容易想到二叉树的深度就是其层数,选用迭代法的层序遍历,每多遍历一层深度+1。2.用递归的方法也能做(简洁写法,隐藏了很多细节)3.递归的完整写法(以前序遍历为例)1.迭代法前序遍历数结点个数。2.迭代法层序遍历数结点个数。3.递归法(代码非常简洁)2.递归法(后序遍历版)3.递归法(前序遍历版)

2024-01-11 11:55:26 376

空空如也

空空如也

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

TA关注的人

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