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

原创 计算机基础八股记录

一个进程由多个线程组成。进程在执行过程中拥有独立的内存单元,而多个线程共享内存。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间。同步:生产者消费者;互斥:竞争某一资源。

2023-08-30 23:27:25 120

原创 C++八股记录

这样一个父类指针指向一个子类对象,想要调用某虚函数时,通过对象内存地址找到的是子类虚函数表,就可以调用子类的版本。这就实现了多态,即一个父类指针指向不同对象,调用相同的函数,表现出不同的形态。只要含有虚函数的类就会为该类生成一个全局唯一虚函数表,虚函数表中记录类中虚函数的入口地址,同时会在每个实例内存的开始生成一个虚函数表指针,指向虚函数表。而当一个子类继承一个有虚函数的父类后,同时也会继承父类的虚函数表,如果子类重写了一个虚函数,就会把虚函数表中该虚函数的地址改成重写后的版本。new分配的内存块;

2023-08-30 23:02:31 846

原创 64.树 | 重建二叉树

根据preOrder和inOrder重建二叉树

2023-05-07 11:26:39 130 1

原创 63.链表 | 从尾到头打印链表

从尾到头打印链表

2023-05-06 00:46:48 102

原创 62.数组 | 二维数组中的查找

二维数组中的查找

2023-05-04 23:59:09 54

原创 61.数组 | 数组中重复的数字

数组中重复的数字

2023-05-04 15:16:22 52

原创 代码随想录 | Day 60(完结) - LeetCode 84. 柱状图中最大的矩形

第0位的左边界(不包含在内)应该是-1,末尾位的右边界(不包含在内)应该是“末尾 + 1”,所以indSmallerLeft[0]和indSmallerRight[height.size() - 1]分别初始化为-1和height.size()。相比接雨水,主要是从“找左、右两边各自最高的柱子”变成了“要找左、右两边各自第一个比当前柱子小的位置”,使其分别作为左、右边界(不包含在内),再令当前柱子的高作为矩形的高,两者相乘得到当前位置的矩形大小。今天是单调栈的最后一天,延续了昨天的接雨水问题。

2022-11-20 00:00:23 332

原创 代码随想录 | Day 59 - LeetCode 503. 下一个更大元素II、LeetCode 42. 接雨水

这个高度取决于当前位置左边部分的最高柱子、和右边部分最高柱子,两者中较小值,再减去当前位置的柱子高度,就是当前位置的雨水高度。在遍历之前,可以将最高柱子高度初始化为当前柱子高度,这样一来,如果左边或右边没有更高的柱子,最后当前位置的雨水量就是0。第3种情况的实现较为复杂,需要首先得到中间柱子,然后使其出栈,再得到左柱子,然后再计算宽度、高度,加雨水量。是三种方法中最难的一种,核心思想是维持单调递减的栈,在出现非递减元素时,弹出栈中元素的同时加雨水,每次所加的雨水数量都是其宽度和高度的乘积。

2022-11-19 17:14:54 634

原创 代码随想录 | Day 58 - LeetCode 739. 每日温度、LeetCode 496. 下一个更大元素 I

不符合的话则需要弹出所有比当前数值小的元素,并同时对弹出元素对应位置的结果赋值(结果就是当前元素下标与被弹出元素下标的差值),最后。为实现这一目的,理论上既需要知道每个元素的值,又需要知道其下标,似乎需要将两者都放入栈中。这样的做法会使得右边没有更大数字的元素永远无法进行res的赋值,而题目要求这些元素的结果均设置为0,所以可以在初始化时就将所有结果设置为0。判断当前元素是否在map中存在,既可以像上面一样使用map.find(),也可以通过判断map.count()的结果是否为0来判断。

2022-11-18 20:58:22 617

原创 代码随想录 | Day 57 - LeetCode 647. 回文子串、LeetCode 516. 最长回文子序列

前两种情况的dp取值都不依赖于其他dp值,而第3种情况的dp[i][j]则依赖于dp[i + 1][j - 1],也就是其左下角位置。所以需要初始化dp矩阵的对角线(对应情况1)以及对角线上每个值右边的第1个位置(对应情况2),这样才能保证在情况3下,每个位置的左下角被填充。)相比上一题,将“连续的子串”改为了“非连续的子序列”,问题也从“回文子串的数量”变成了“最长回文子序列的长度”。因为问题的转变,所以定义方面,这道题的dp[i][j](i ≥ j)变成了“s[i : j]的最长回文子串长度”。

2022-11-17 18:04:34 408

原创 代码随想录 | Day 56 - LeetCode 583. 两个字符串的删除操作、LeetCode 72. 编辑距离

对于第1种可能,由于dp[i - 1][j - 1] + 1要么与dp[i - 1][j]相等,要么与dp[i][j - 1]相等(因为删除次数+1对应多删1个元素,即多一个元素),所以dp[i - 1][j - 1] + 2等于dp[i - 1][j] + 1或dp[i][j - 1] + 1。两者相等时,相对于word1[0 : i - 2]和word1[0 : j - 2]不需要额外的删除次数,所以删除次数仍然是dp[i - 1][j - 1];另外这两道题的初始化部分,不再是全部初始化为0了。

2022-11-17 00:20:28 231

原创 代码随想录 | Day 55 - LeetCode 392. 判断子序列、LeetCode 115. 不同的子序列

第0行,对应s为空,dp[0][j](j > 0)对应空字符“删除任意字符后出现t[0 : i - 1]”的个数,空字符无论怎么删除都还是空字符,所以有0中删除方式,dp[0][j](j > 0)都应该初始化为0。)需要首先将问题转化为“求s和t的最大相同子序列长度”,用dp[i][j]表示“s[0 : i - 1]和t[0 : j - 1]的最大相同子序列长度”(使用i - 1、j - 1而不用i、j的原因与之前一样,还是为了后面的初始化方便)。不断的右移t指针,使t指针所指的值匹配s指针所指的值。

2022-11-16 02:48:08 150

原创 代码随想录 | Day 53 - LeetCode 1143. 最长公共子序列、LeetCode 1035. 不相交的线、LeetCode 53. 最大子序和

对于text1[i - 1]与text2[j - 1]相等的情况,最长公共子序列长度相比没有text1[i - 1]和text2[j - 1]时就要增加一位,所以dp[i][j] = dp[i - 1][j - 1] + 1;),子序列不再要求是连续的,剩余地方都与其一样。实现中需要注意,因为为了初始化的方便而采用了额外多一行、一列的dp矩阵,所以与dp[i][j]对应的是text1[i - 1]和text2[j - 1]是否想等的判断,而不是text1[i]和text2[j]。

2022-11-16 00:57:35 231

原创 代码随想录 | Day 52 - LeetCode 300. 最长递增子序列、LeetCode 674. 最长连续递增序列、LeetCode 718. 最长重复子数组

所以要计算dp[i]的话,就要从0遍历到(i - 1)位置,遇到比nums[i]小的数字nums[j],就将dp[j]加上1,然后取所有dp[j] + 1(j < i)当中的最大值作为dp[i]的结果。这一题要用到二维dp数组,dp[i][j]定义为“对于nums1的[0, i]部分,nums2的[0, j]部分,两者分别以nums1[i]和nums2[j]结尾的最长重复子数组长度”。当nums1[i]与nums2[j]相等时,这一长度就在dp[i - 1][j - 1]的基础上再增加1;

2022-11-15 00:03:51 169

原创 代码随想录 | Day 51 - LeetCode 309.最佳买卖股票时机含冷冻期、LeetCode 714.买卖股票的最佳时机含手续费

这道题的重点仍然是状态的定义和划分,状态整体上仍然分为“持有”和“不持有”两大类。其中“不持有”又分为“当天卖出”、“当天是冷冻期”、和“当天已经过了冷冻期”这3种状态,加上“持有”共计4种状态。将“持有”、“当天卖出”、“当天是冷冻期”、和“当天已经过了冷冻期”分别设为状态0~3。所以要做出的相应改变就是,从“持有”状态向“不持有”状态转移时,要减掉手续费,也就是将原本的dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] +主要是第1题的冷冻期问题比较复杂。

2022-11-14 22:14:16 248

原创 代码随想录 | Day 50 - LeetCode 123. 买卖股票的最佳时机III、LeetCode 188. 买卖股票的最佳时机IV

第0天就处于状态1的话,只可能买入第0天的股票,所以dp[0][1] = -prices[0];虽然第0天无法处于状态2,但一方面可以看作是第0天买入后又立即卖出,另一方面卖出时的利润都是不低于0,设置为0可以保证后面的比较大小顺利进行,所以dp[0][2] = 0;由于最多可以买卖两次,所以原本“持有”和“不持有”这两种状态不再够用,需要扩展为“未曾买卖”、“买过第1次”、“卖过第1次”、“买过第2次”、“买过第2次”这5种状态,第i天每个状态下能获得的最大利润对应dp[i][0]~dp[i][4]。

2022-11-14 21:07:10 242

原创 代码随想录 | Day 49 - LeetCode 121. 买卖股票的最佳时机、LeetCode 122.买卖股票的最佳时机II

所以“第i天持有”的第2种情况,也就是“之前未买入,第i天买入”需要改为“第(i - 1)天未持有,第i天买入”。所以状态转移方程就可以总结为dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i])和dp[i][1] = max(dp[i - 1][1], -prices[i])。dp数组的第i天有两个数值,dp[i][0]表示第i天“不持有”股票对应的最大所得现金,dp[i][1]表示第i天“持有”股票对应的最大所得现金。

2022-11-13 18:06:34 273

原创 41.动态规划(9) | 打家劫舍、打家劫舍II(h)、打家劫舍III(h)

而如果打劫的话,就意味着上一个房屋不在考虑范围内,所以要取上“上一个房屋对应的dp值”与“当前房屋价值”的和,即dp[i - 2] + nums[i]。而如果打劫当前节点,那么其左右子节点都不能被打劫,只能选择各自dp的第0位,再加上当前节点的val,对应cur->val + dpLeft[0] + dpRight[0]。如果打劫当前节点,那么当前点的左右子节点就都不能被打劫了。所以应该考虑当前节点的孙子子树,也就是当前节点的“左子节点的左右子节点、右子节点的左右子节点”,这4个节点作为根节点的4棵树。

2022-11-07 22:00:50 267

原创 40.动态规划(8) | 单词拆分(h)、多重背包

代码中需要注意,递归的循环中,i一定是从indBegin开始的。自己起初是设置为从indBegin + 1开始的,那么下一层递归的indBegin参数就不再应该是(i + 1)了,而应该是i,否则会错误地略过当前层的第(indBegin + 1)个元素。该问题有多种解法,其中比较容易理解和实现的是转化为01背包问题,也就是把每个数量为n的物品拆分为n个数量为1的物品,然后用01背包的解法解决。,当前的目标字符串,也就是当前背包容量,对应的物品是“当前目标字符串的所有后缀”,而所有物品就是。

2022-11-07 15:46:33 238

原创 39.动态规划(7) | 爬楼梯、零钱兑换、完全平方数(h)

第1题(LeetCode 70. 爬楼梯 (进阶))是day 38中的第2题,当时用了斐波那契数列的解法。也可以将其看作完全背包问题,背包容量对应总台阶数,物品对应每次能上的台阶数。比如在该问题中物品数共2件,第一件物品的重量和价值都是1,第二件物品的重量和价值都是2。具体的背包问题跟day 44中的第3题(LeetCode 377. 组合总和 Ⅳ)一样,是求排列数量。所以按照dp[j] += dp[j - weight[i]]的状态转移方程,dp[0] = 1作为初始化,外层循环遍历背包、内层循环遍历物品

2022-11-05 20:23:44 478

原创 38.动态规划(6) | 完全背包(h)、零钱兑换 II、组合总和 Ⅳ(h)

dp[i][j]的定义是与01背包问题一样的。所以用dp[i][j]表示“有前i件物品,装满容量j的方法数”的话,状态转移方程就变成了dp[i][j] = dp[i - 1][j] + dp[i][j - weight[i]]。所以状态转移公式中的max()需要改为min(),同时将dp[0]以外的DP数值初始化为一个“很大的值”,dp[0]还是初始化为0。所以最终的状态转移方程是dp[i][j] = max(dp[i - 1][j], dp[i][j - weight[i]] + value[i])。

2022-11-05 00:47:02 138

原创 37.动态规划(5) | 最后一块石头的重量 II(h)、目标和(h)、一和零(h)

多了当前的第i件物品后,会新增将当前第i件物品装进去的若干装法,为保证空间大小j需减小为(j - weight[i]),所以这部分装法数量对应dp[i - 1][j - weight[i]]。那么问题就转化为了“背包维度0容量为m,背包维度1容量为n,每个字符串对应一件物品,每个物品的价值都为1,维度0的重量为该字符串中字符'0'个数,维度1的重量为该字符串中字符'1'个数,这种情况下的01背包问题”。而对于这两个集合,只要求得其中一个的和,用“整体和”减去它,便能得到另一个的和了。两者之差尽可能地小。

2022-11-04 01:16:29 100

原创 36.动态规划(4) | 01背包(h)、分割等和子集(h)

另外在矩阵版本的双重循环中,由于(j - weights[i])可能会小于0,所以在其小于0时,直接选择上方的值dp[i - 1][j]。又因为遍历方向是从右向左,所以j是在递减的,那么(j - weights[i])就也是在递减。所以,只需要将内层循环进行到j - weights[i] < 0为止就可以了,所以内层循环条件可以设置为j - weights[i] >= 0,即j >= weights[i]。而对于容量,只能从0开始初始化,所以dp[i][0]对应背包最大容量为0,而不是最大容量为1的情况。

2022-11-02 23:56:46 163

原创 35.动态规划(3) | 整数拆分(h)、不同的二叉搜索树(h)

如果左子数有j个节点,那么右子树就有(i - 1 - j)个节点,j可以从1取到(i - 1),所以总共有(i - 1)种情况。这其中j和(i - 1 - j)都一定是小于i的,所以其左子树的类型就有dp[j]种,右子树的类型就有dp[i - 1 - j]种,两者相乘就得到了“左子树有j个节点情况下,整个树可能的结构数”。对于数字i,它总是会被拆分成2个或2个以上的数字。所以这道题的状态转移方程是dp[i] = max(j * (i - j), j * dp[j]),其中j需要从1遍历到(i - 1)。

2022-10-31 19:47:06 103

原创 34.动态规划(2) | 不同路径、不同路径 II

初始化方面,由于第0行的所有点都是只能由出发点向右走的,第0列所有点都是只能由出发点向下走的,所以第0行和第0列的值都应该是1。题解中还给出一种数论的解法。如果惯性思维将其初始化为1,那对于“第0行的第0个元素就是障碍物,但其他行的第0列元素并没有障碍物”的情况,由于是从第1行开始遍历的,那就会错误地将其他行的第0列元素设置为1。如果使用搜索的方法,那么搜索树的深度就是m + n - 1(深度按从1开始计算),二叉树的节点数就是2^(m+n-1)了,对应时间复杂度O( 2^(m+n-1) ),所以会超时。

2022-10-31 00:54:50 101

原创 33.动态规划(1) | 斐波那契数、爬楼梯、使用最小花费爬楼梯

所以已知了第i - 1阶和第i - 2阶楼梯的最小花费后,再令两者各自加上自己前进所需的花费,即cost[i - 1]和cost[i - 2],就得到了2种路线和对应的花费。从两者中取较小的一个当做第i阶的花费即可,所以dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]。因为每次只能上1阶或2阶,所以对于i阶楼梯,它的上一步要么是第i - 1阶,要么就是第i - 2阶。

2022-10-30 22:47:54 122

原创 32.贪心(6) | 单调递增的数字(h)、买卖股票的最佳时机含手续费(h)、监控二叉树(h)

第1题(LeetCode 738. 单调递增的数字)自己的思路跟题解比较相近,但有缺陷,且最终没有实现成功。贪心策略是让不符合要求的右半部分数字都变为9,且同时左半部分也要改变,使得变化后的数字要小于原数字。所以关键问题是找到上述左右部分的分割点。 具体做法是首先将数字转化为对应的字符串。因为题目要求从左至右要满足非递减关系,所以如果从左向右遍历的话,如果为了满足当前数字小于右边数字的要求而让当前数字减1,那么当前数字左边的数字,或许又不满足要求了。所以应该从右向左遍历,只要遇到当前数字大于右

2022-10-30 19:51:52 85

原创 31.贪心(5) | 无重叠区间、划分字母区间(h)、合并区间

排序后,将首个区间的左边界设置为begin,右边界设置为end,然后开始遍历剩余区间,贪心目标是让当前区间尽可能多地与其他区间合并。所以,需要预设一个最短段下标,将其设置为第一个字母出现的最大下标,并在遍历时不断根据新字母出现的最大下标,将其更新为更大的值。只要遍历到该最短段下标,就说明段内的所有字母都出现在当前段内,不会出现在之后,于是就可以将当前遍历过的部分当作一段,并开始下一段的遍历。在遍历时,遇到区间的左边界大于或等于重叠区间右边界时,就对不重复区间数+1,并更新重叠区间右边界为当前区间的右边界。

2022-10-29 22:43:58 85

原创 30.贪心(4) | 柠檬水找零、根据身高重建队列(h)、用最少数量的箭引爆气球(h)

此外,可以用一个新的vector来保存结果,当要插入某个元素(对应下标i)时,因为结果中保存的元素身高都不小于该元素,其目标插入位置就是people[i][1],不需再用一个循环来确定。比如输入为[[7,0],[5,0],[7,2],[6,1],[5,2],[7,1]]时,上面错误代码的输出就会是[[7,0],[5,0],[7,1],[6,1],[7,2],[5,2]],而正确答案是[[5,0],[7,0],[5,2],[6,1],[7,1],[7,2]]。函数,需要再次熟悉下。

2022-10-29 19:31:19 331

原创 29.贪心(3) | K次取反后最大化的数组和、加油站(h)、分发糖果

首先对于第0个点,由于sumCur是第0~i个点的汽油剩余量的和,相当于模拟了从第0个点出发的过程,而到第i个点时汽油剩余量却变成了负数,说明从0个点出发不成功。而对于从第1个点出发的选择,因为第0个点的汽油剩余量一定是非负数(否则在第0个点时,sumCur就已经被更新为0了),所以从第1个点出发的sumCur一定是小于或等于从第0个点出发的sumCur的。那么既然从第0个点出发的sumCur都已经是负数,从第1个点出发的sumCur就也一定是相等或更小的负数了,所以从第1个点出发也是不行的。

2022-10-29 13:44:29 301

原创 28.贪心(2) | 买卖股票的最佳时机II、跳跃游戏(h)、跳跃游戏II

所以可以探索下下标1~3数字的覆盖范围,于是得到下标1数字2的覆盖范围是下标2~3,下标2数字1的覆盖范围是下标3,下标3数字0的覆盖范围为空。而对于数组[2, 3, 1, 1, 4],下标0数字2的覆盖范围是下标1~2。具体来说,如果设当前下标为0,当前最多能跳2步,对应的下两个数字是[5, 1],那么当前跳1步的话,下一步的最大跳跃下标是1 + 5 = 6;这一题同样有DP解法,但DP在之后的章节会专门练习,其中也会有这一题,所以这里和之后的贪心算法题目中不再研究DP解法,在之后的DP章节中再研究。

2022-10-28 22:49:17 1010

原创 27.贪心(1) | 分发饼干、摆动序列、最大子序和(h)

反之,如果上一个转折点是山峰,峰点数字被保存为pre,那么遇到比pre小的数字也不能说明就是山谷,只能说明比山峰小,它之后可能紧跟更小的数字。而对于一些在山腰的数字,虽然在最优解下是被认定为山腰的,但这并不妨碍它可以被认定为山峰/山谷,只不过得到的不是最优解,最坏情况下,它被认定为山峰/山谷后得到的答案是1。而初始化方面,因为题目说一个数字也是1个摆动序列,所以对应的最小值为1,所以就需将dp的第0行2个数字都初始化为1,并在遍历nums时,每次都将nums[i]的个数字也都初始化为1。

2022-10-28 18:19:06 218

原创 26.回溯(6) | 重新安排行程(h)、N皇后、解数独(h)

第1题(332. 重新安排行程)自己艰难地AC。这道题用DFS更合适些,但还没刷到那部分,就先练习下回溯解法。按照自己的思路,首先对备选车票按照目的地的字典序排序。然后向存放结果的vector,res中添加"JFK",再用day 29中排列问题的解法对车票进行循环遍历和递归。当当前元素对应的used表为true,或当前车票不是上一张车票的后继时跳过。 方法比较简单,但经历了多次失败。起先是因为将递归函数出口像之前的题目一样直接写成了:而其他地方也没有任何处理。如果写成这样,递归函数会返回

2022-10-24 00:07:09 272

原创 25.回溯(5) | 递增子序列(h)、全排列、全排列 II(h)

但本题中,由于数组中有重复元素,如果用上一题的方法则无法区分当前树枝上两个或多个数值相同的数字,所以应该将bool数组的大小调整为与备选数组一致,这样才能与备选数组中的数字一一对应。这是因为排列不同于组合,在树层中遍历的起始下标是0,而原本的i > begin也就替换为i > 0,这就导致如果上一层被选取的元素恰好与当前层第1个待选元素相等的话,当前层的元素无法被选取。一样,题目中可能有相等的数字,但要求结果不能有重复的序列。而题目又要求结果的排列不能重复,所以需要同一数层的去重,这里的去重针对的是。

2022-10-19 23:31:31 113

原创 24.回溯(4) | 复原IP地址(h)、子集、子集II

里面最简便的第3种实现方式,即添加每个重复区间的第一个元素并递归后,对当前重复区间的其他元素continue。类似,在已知上一个分割点的情况下,在递归函数中循环遍历下一个可能的分割点。所有节点恰好满足不重复且是子集的要求,所以在实现时也只需要套用模板,但需要把res.push_back(path)从递归出口移到函数开始处,让每次递归,即每个节点都能运行这一句,使每个节点都被放入到结果当中。而自己的写法是不论取或不取,都进行递归,相比前者会对不取元素的情况进行处理,所以像这种取子集的题就很适合。

2022-10-18 22:49:12 139

原创 23.回溯(3) | 组合总和、组合总和II(h)、分割回文串(h)

所以在DP过程中,每个点的true或false取值取决于其左下角的点,那么在计算第i行之前,要首先得到第i + 1行的计算结果,就需要在行方向上倒序遍历了。同时它也表示每个元素在当前层的已使用情况,与在树枝上的含义相反,如果值为false,说明在当前层已经被使用过,不能再使用与其值相等的元素。而每行从斜对角线开始的前2个元素,都是没有对应的左下角点值的,所以需要进行特殊的判断。这样的方法也可行但对于指针的处理比较麻烦,很容易出错,所以还是建议使用题解的方案,或者下面的简化版本(题解中的第二种解法)。

2022-10-18 17:38:07 103

原创 22.回溯(2) | 组合总和III、电话号码的字母组合

第1题(216. 组合总和III)相比day 24中的模板只是对组合中数字的和限定为了n,所以在递归出口处判断和是否为n即可。记录和的具体方法可以像之前day 18中第2题(112. 路径总和)一样转化为减法,判断最终结果是否为0。这道题按上面的写法虽然也能AC,但还可以优化,重点在于剪枝,横向和纵向都可进行剪枝:其中,横向上的剪枝是我自己没有考虑到的。 第2题(17. 电话号码的字母组合)需要首先把每个数字按键和对应的多个字母记录整理下来,并同之前一样设置2个全局变量path和res。

2022-10-17 22:25:10 186

原创 21.回溯(1) | 77. 组合

自己之前在其他题目中还实现过另外一种回溯方法,将上面的“在每次回溯中横向遍历所有下一个数字的可能”变为了“将每个数字都分为‘取’和‘不取’这2种可能”。在自己的编译器中用全局变量cnt统计了n和k分别取20和16时,递归函数的运行次数,发现该方法的cnt约是第一种方法cnt的2倍左右。分析原因,发现这种方法在不取某个值时,也会进行递归,而第一种方法则不会,效率更高。主要内容是回溯的理论基础和基本代码模板,需要注意一定要将一直保持不变的vector设置为全局变量,否则有可能超时。

2022-10-17 20:48:11 138

原创 20.树(9) | 修剪二叉搜索树(h)、将有序数组转换为二叉搜索树、把二叉搜索树转换为累加树

自己AC的递归方法是将数组范围作为递归参数,根据坐标取数组的中间数作为中间节点的val,再用数组的左半部分递归建立左子树,用数组的右半部分递归建立右子树。)自己实现的递归解法会出现奇奇怪怪的报错“ERROR: AddressSanitizer: heap-use-after-free on address”,测试用例是一颗普普通通的树[2, 1, 3],low = 3,high = 5。题解的递归解法也是反中序遍历,只是当前节点的val虽同样采用全局变量,但用来保存前继节点val的值。

2022-10-16 17:10:22 131

原创 19.树(8) | 二叉搜索树的最近公共祖先、二叉搜索树中的插入操作、删除二叉搜索树中的节点(h)

不是上面2种情况的话,再判断当前节点与p、q的val的大小关系,如果都比当前节点小,就递归向左查找,反之向右查找。删除节点的函数返回删除后,需要调整部分的树的根节点。这样一来,对于非叶子节点的这个赋值是等于没有操作的,只有对叶子节点,才会插入新建的节点。)的递归法自己AC的思路是判断当前节点是否可以插入,插入条件为应该插入左边且左节点为空,或者应该插入右节点且右节点为空。迭代法沿用使用parent记录父节点的思路,不断向下查找,直到cur为空节点,parent为叶子节点,再对parent插入。

2022-10-15 22:12:31 65

空空如也

空空如也

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

TA关注的人

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