自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

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

f[i]表示爬到第i层的最小花费。转移方程:f[i] = min(f[i-1] + cost[i-1], f[i-2] + cost[i-2])。初值确定:f[0] = f[1] = 0。先考虑转移方程,设走到第i阶楼梯有f[i]种方法,一次能走1格或2格楼梯,所以f[i] = f[i-1] + f[i-2],和费波纳列数类似,也用了局部变量取代数组。这里a为f[i-2],b为f[i-1],c为f[i]。最经典的动态规划题,先确定转移方程,题目直接给出了。设f[i]为前i项的斐波那契数。

2025-02-12 16:49:20 240

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

注意点:num[i] = 9是错误的,这样相当为num[i]赋值ASCII码为9的字符。开始没标识flag,这样没达到局部最优,因为大位上--了,所以后面的位数放心加。故要flag标识--后的一位然后全取位数为9。局部最优:使用right判断一次区间合并时最大尺寸能扩展。找到对应的left和right,然后将其加入数组中。

2025-02-12 09:13:09 137

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

局部最优:找到一支箭能贯穿最多的数组,那首先要让不同元素间有交集,首先排序,再看重合情况:1. [1, 3], [2, 4]中间有重合,重合区间是[2, 4];2. [1, 5], [2, 4]前者覆盖后者,重合区间时[2, 5];所以重合区间范围[points[i + 1][0], min(points[i][1], points[i+1][1])]。可以结合上一问,既然求的是多少箭能贯穿重合的数组;设不重叠数组的数目 = 所有数组数目 - 重合数组的数目。452. 用最少数量的箭引爆气球。

2025-02-11 08:39:15 111

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

分别在从前往后遍历 判断右边数是否大于左边数,从后往前遍历 判断左边数是否大于右边数。这次顺序和条件不能反,拿从前往后遍历 判断右边数是否大于左边数举例,如果右边数大则更新右边数,其基于左边数赋值,而左边数(更前的数)已经提前做好赋值了。利用全局总值和区域总值来解决问题 将区域总值看成两个区间,一个正区间,一个负区间。每当区域总和为零时,就可将其看做一个负区间,而我们要找的是正区间,因为只有正区间才能去抵消那些负区间的值。5元既能找零10元一部分和20元一部分,10元能找零20元一部分;

2025-02-09 17:16:52 199

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

因为可以在同一点购买出售,所以只要保证第二天卖出有利润,都可以买入,反映到数组上条件为nums[i] < nums[i+1],然后把所有利润累加。但是疏忽了一点,当有元素为0时,不能保证一定能跳到后面的元素。比如说[3,2,1,0,4],无论怎么跳都只能到0这个点,所以遍历范围是不合理的。首先得排序,对于正负元素混合的数组首先对最小的负数取反;对于全正数的数组,则k为偶数可以取回原数,k为奇数则取最小的数字为负。思路是一次跳跃中尽可能大地覆盖元素,然后从已覆盖的元素中判断下一次能不能到达最后一个元素;

2025-02-08 01:07:22 294

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

up和down代表下一个点和当前点之间的状态(如果序列增加,当前点处于山峰下一个点得是山谷,因此down为true,up为false),这样的好处是不用考虑平直的情况。用了前缀和的思路,子集就是前缀和数组任意两个元素相减。设立minVal记录i之前的最小值,然后比较最大值和当前指向元素减去minVal即可。直接用双指针法进行比较,如果饼干够小孩吃,那就判断下一个小孩够不够吃下一块饼干;如果不够,则判断同一个小孩够不够吃下一块饼干。

2025-02-07 12:23:32 191

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

和上一题不同点在于元素可以是重复的,那么在上一题的基础上要加上去重的环节。经典去重环节排序后used数组若为false且两个元素值相同表示同层有重复元素要去除一种情况,true表示同树枝会有重复元素(这题要保留纵向的重复元素)。全排列和子集组合的不同点在于,他每次都要遍历整个数组,所以循环中要设i = 0。但是遍历不可避免的遍历到自身,这里用used数组表示该元素已被访问;遍历时要跳过这种情况。

2025-02-06 02:44:36 126

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

这题套用上一题的框架,不同点在于可加入相同的值;这类遇到重复的问题需要用到used数组帮助判定是否是数组重复;当true时说明已经加入过其他相同的值但是可以再加入,当false时说明当前数组没有加入此值,但要跳过这类情况因为会和之前的数组重复,需要剪枝。子集和组合的区别:子集加入每一个节点而组合加入每一个叶子节点。2. 每段的数值在0-255之间,且二位数以上首位数字不能为‘0’1. num表示段数,超过3就得直接返回,后面的情况不用考虑。

2025-02-03 12:31:26 138

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

此题的要求是可以使用重复的元素但不能选用重复的组合。我们设置一个数组来表示对应元素是否之前被使用过。如果false,说明不是重复选择该元素,跳过该情况;如果true,说明重复选择该元素,考虑该情况。整体逻辑是判断切割的字串是否为回文串,所以终止条件是遍历完整个字符串(if(s.size() == startID)。开始的想法是遍历所有的元素,但是这样会导致重复(例如[2,3,3]和[3,2,3]),不出意外地爆栈了。加入了排序+剪枝后能通过测试。

2025-02-03 02:38:00 127

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

综合性很强,采用数字映射字符串的方式表示回溯。根据模板图可得此处横向遍历数字对应的字符串,而纵向则是遍历一连串数。可以画一张示意图,这里要多保存sum参数用来比较大小,条件都放到最上面,重点是剪枝,不然会超时。基础题,套用回溯模板直接可以解出来。

2025-01-31 19:43:17 175

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

根据实例可看出是右中出遍历,那么按照递归的格式可以出模板;. 这题关键在于要转换成平衡二叉树,在看到输入参数有数组突然就想到找到中间节点再分成左右节点进行迭代。采用前序遍历,再根据要求可得:第一个低于下限值的左子节点全部舍弃,高于上限值的右子节点全部舍弃。

2025-01-28 03:59:32 162

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

公共祖先:利用回溯从底向上搜索,遇到一个节点的左子树里有p,右子树里有q,那么当前节点就是最近公共祖先。在二叉搜索树中,从上向下去递归遍历,第一次遇到的节点是数值在[q, p]区间内那么它即为公共祖先。本题可以不改变整体结构,二叉搜索树本身是有序的,只要找到符合要求的叶子结点在下面添加新的节点即可。3. 左右节点都不为空,那么把左节点平移到右字树上最小的节点左边也能符合二叉搜索树的规律。2. 左节点或右节点有一个为空,那么直接返回另一个子节点。1. 没有左右子节点,那么该节点直接删除。

2025-01-26 22:42:51 117

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

和上一题一个类型,可以为每个节点保存一个计数,计数最大的节点值放入数组中;要注意的是搜索到更大的计数时要将之前的数组清空。二叉树的特性是两个相邻节点之间可能存在最小绝对差,所以可以中序遍历同时计算节点间的差值,再分别比较得出答案。这题看了答案才有思路。自底向上(后序遍历),然后判断根节点和其公共祖先的位置关系。这里递归传递参数用的很妙。

2025-01-22 18:58:25 119

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

简而言之就是把二叉树搜索树上所有节点的值投影到一条水平线上,由小到大排序。此题即用到了其搜索特性。中序遍历二叉搜索树会是从小到大的顺序,所以将其值保存到一个数组中再判断是否按从小到大顺序排列。根据合并的规则可以写出不同的条件对应情况,再采用前序遍历,最后返回根节点。这题有点像昨天的中序遍历和后序遍历得出前序遍历的题,都是拆分成两个数组分别进行递归。

2025-01-20 05:16:19 164

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

由于后序遍历的最后一个元素为root的值,先找出后再在中序遍历数组里找出其位置作为分割点。后序遍历和中序遍历的子数组长度相同,所以又能得出leftPostoder和rightPostorder。这里用了前序遍历,参照了递归的模板,把保存符合条件的节点(最底层最左边的节点)。注意点:遍历不能传入depth++或者++depth,因为这样会修改栈中depth的值,随着递归depth的值会直接改变。二叉树本质由一个个子二叉树构成, 子树遵循的遍历规律符合整体规律,所以把根的左节点和右节点都看作新的根节点,

2025-01-11 01:59:59 492

原创 代码随想录算法训练营第十五天 | 二叉树 110.平衡二叉树 257. 二叉树的所有路径 404.左叶子之和 222.完全二叉树的节点个数

所以还是递归的同时标记左右子树是否差值大于1,不符合条件就设定为-1直接返回根节点,然后求根节点的高度即得出答案。先遍历每一个节点,再判断其左节点是否为题目要求的左节点 if(root->left &&!root->left->right),再求和即可。前序遍历,遍历到叶子节点再把保存到数组中的节点写成字符串,最后加入到结果中。注意的点:中止条件是最后一个节点而不是空节点,因为只需要处理最后一个节点,不用考虑空结点的情况。使用任意遍历方式,只需保证访问到一个节点,总数+1即可。

2025-01-06 21:42:24 173

原创 代码随想录算法训练营第十四天 | 二叉树 226.翻转二叉树 101. 对称二叉树 104.二叉树的最大深度 111.二叉树的最小深度

对称的本质是左节点的左节点= 右节点的右节点,左节点的右节点 = 右节点的左节点。前中后遍历都只能访问一个节点的左右子节点,但这里必须同时知道左右节点的子节点的值,所以要同时访问两个树。比如一个节点有左节点而没有右节点,如果没有判断他就会计算得出最小深度位于其右节点的情况(但是右节点为空节点,不能作为最小深度计算)。这里采用了前序遍历(后序遍历也可),本质是先处理节点,再不断访问左节点,到头(没有左子节点),回退到上一个节点再访问右节点,然后继续不断访问左节点......相比递归感觉这样思路更加清晰一些。

2025-01-04 16:46:08 290

原创 代码随想录算法训练营第十一天 | 栈与队列 150. 逆波兰表达式求值 239. 滑动窗口最大值 347.前 K 个高频元素

这题开始用的暴力求解法,但是时间复杂度为O(k*n)太高,看了解题思路后醍醐灌顶。滑动窗口可以等效为双向队列尾部插入(push_back)一个元素,队首弹出(pop)一个元素。deque是我们的理想数据结构,但它没法直接求出队列中的最大元素。大堆顶(堆顶值最大,然后逐步减小)和小堆顶(堆顶值最小,然后逐步增大)很难记,每次用都得查一下它比较器的顺序。下图比较器left.second > right.second返回true,表示左边元素优先级较低(即更大的值放在更低的位置),即是小顶堆。

2025-01-02 18:55:12 182

原创 代码随想录算法训练营第十天 | 栈与队列 232.用栈实现队列 225. 用队列实现栈 20. 有效的括号 1047. 删除字符串中的所有相邻重复项

这道题没有那么直观,思想是除了队列尾部的元素暂时保存到另一个容器(可用vector等其他容器)中,目的是把原来队列尾部的元素置于队列头部,这样队列就能处理它。再把队列尾部的元素pop掉,最后把其他元素再重新按照顺序加入回来。比如说第一个栈插入(1 2 3),另一个栈接受前一个弹出来的数(3 2 1)此题要求左边括号按顺序匹配右边括号,因为是左边括号必须在右边括号前,很容易想到栈的特点FILO。此题和上一题类似,也是运用了栈的特性消除重复项,判定条件:不重复的元素将其插入,若相邻元素重复则一起消除。

2025-01-01 14:24:26 246

原创 代码随想录算法训练营第九天 | 151.翻转字符串里的单词 卡码网:55.右旋转字符串 28. 实现 strStr() 459.重复的子字符串

有点类似昨日的最后一题,都涉及到一些逻辑处理。这题跳过空格,也可以用指针和substr提取字符串做处理。我这里使用istringstream提取字符串,再创建额外的空间写出翻转后的结果(感觉这样会简单很多。思路简单,找到pos位置后,很容易想到分成两个字符串再拼接;也可以从原地后往前插入字符。不创建另外的空间,这里采用反转字符串再反转字符,配合空格的逻辑处理也能解决。要用到KMP算法,先插个眼。

2024-12-29 17:30:11 266

原创 代码随想录算法训练营第八天 | 344.反转字符串 541. 反转字符串II 卡码网:54.替换数字

原地修改: 这里使用了replace函数,避免额外创建新字符串,但是整体时间竟然没有节约多少。大概是replace函数从前向后填充,每次添加元素都要将添加元素之后的所有元素整体向后移动。题目要求把数字换成number,则创建一个字符串然后进行拼接。这里使用了额外的开销,还可以试试原地修改,但是代码会复杂一些。字符串本质还是放在一个连续的数组里,所以反转出现立马就想到调用栈(FILO)代码随想录使用从后向前填充,这个时间耗时最少。个字符“可看出要建立以2k为区间的循环;再结合上一道题分不同的情况得出答案。

2024-12-28 22:10:16 535

原创 代码随想录算法训练营第七天 | 哈希表理论基础,454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

我分别用了两个哈希表,统计了两个数之和的出现次数;c数组元素+d数组元素 = -3,出现了4次;= 0而是 > 0,特例为第一个数组"abcd", 第二个数组"abcdabcd",这样判断完哈希表的值为负数,一开始疏忽了这点。但是要处理的条件很多,一不留神就会忽略。我看了思路然后做题,也没能考虑齐全条件,错误见注释。3. 双指针法能处理的也只有两个数字,数字变多后还是得放入循环中解决。2. 这儿要返回具体的数,但是哈希表只能反映次数和总和,所以不能用。除了双指针法想不到别的方法了,看了答案也只有这个办法。

2024-12-25 17:32:51 263

原创 代码随想录算法训练营第六天 | 哈希表理论基础 ,242.有效的字母异位词 349. 两个数组的交集 202. 快乐数 1. 两数之和

看了参考答案就知道这个数迟早会陷入死循环,那就可以用unordered_set记录已经出现过的值,如果再次出现那就说明陷入死循环,直接return false。,实际却返回[0,1,2],但你的代码无法正确处理这种情况。所以还是用unordered_map记录下出现的次数比较好,此处还是用了先找后插的原则。就是不考虑字符的排序,只考虑字符的数目是否相等。可以用哈希表来记录两个字符串中字符的数目,然后比较这两个哈希表是否相等(模板库中的容器支持。中的元素,但这样会丢失数组中元素的顺序和重复信息。

2024-12-23 19:34:19 577

原创 代码随想录算法训练营第四天 | 链表理论基础, 24. 两两交换链表中的节点,19.删除链表的倒数第N个节点,链表相交, 142.环形链表II

再次感觉到虚节点dummy的妙用,这里很容易想到用三个指针去表示节点的移动。最后要注意返回的不是head而是dummy>next,因为整体是节点的移动所以初始头节点已经发生变化。这题直觉是双指针法,但是摸不清具体规律。看了答案,总结下来就是先让快慢指针相遇,再让满指针和链表头开始移动的指针相遇,他们所在地点是入口函数处。整体思路很明确,倒数第n个节点 = 第二个指针比第一个指针先走n - 1步,然后两个指针一起跑直到第二个指针直到末尾。19.删除链表的倒数第N个节点。24. 两两交换链表中的节点。

2024-12-23 16:59:21 234

原创 代码随想录算法训练营第三天 | 链表理论基础,203.移除链表元素,707.设计链表,206.反转链表

题目思路本身很明确,难点在于头节点如何定义。按照往常的习惯虚节点定义为ListNode(0,head)在这里就不适用,最后打印会多出一个0。难点在于对边界的判断,还有要保证判断的节点非空节点。

2024-12-16 17:05:20 162

原创 代码随想录算法训练营第二天 | 数组理论基础,209.长度最小的子数组,59.螺旋矩阵II

自己有一些头绪,但是想不到是用这种模拟的方式思考。我自认想了很多边界,但是把数值N扩大发现又要处理很多边界条件,所以还是按照视频中提到的做法去做模拟。代码本身不难,难点是思考到这一步。这道题我想到是滑动窗口了,第一版没看视频写了如下代码,很遗憾超过时间。

2024-12-13 20:36:30 187

原创 代码随想录算法训练营第一天 | 数组理论基础,704. 二分查找,27. 移除元素,977.有序数组的平方

emmm...感觉对C++比较友好,直接可以用std::remove和std::vector::erase完成题目。C++20引入了erase_if的用法,这里也可以使用,顺带一提的是之前面试碰到过关于remove_if的问题。,即在while寻找中每一次边界的处理都要坚持根据区间的定义来操作。这次target用左闭右开的区间定义,就是。(深有感触,第一遍写了很多case)。

2024-12-12 02:45:21 260

空空如也

空空如也

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

TA关注的人

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