- 博客(33)
- 收藏
- 关注
原创 代码随想录打家劫舍+树形DP入门
递推公式:根据不相邻原则进入房间i能够偷到得总金额是由进入房间i-2或者房间i-3累计得到的,dp[i] = value[i] + max(dp[i-2], dp[i-3]);含义:下标0,1表示状态不偷当前节点和偷当前节点,数值表示在这两种状态下得到的最大金额。在抢第一个房间就不考虑最后一个,反之,抢最后一个房间就不考虑第一个房间。递推偷当前根节点就不能偷左右儿子,不偷当前根偷不偷左右儿子都行取最大值。数组:进入房屋i能够偷得得最大金额dp[i]初始化dp[0],dp[1],dp[2]
2025-04-19 19:05:16
79
原创 代码随想录背包问题完结
该题在动态规划思路方面与上题一致,但是每个物品都是一个完全平方数这样才能符合题意。如果某一种物品有m个,就把他们当作m种属性相同的物品,这样就转化为01背包了。动态背包,个人觉得还是结合双指针法来理解比较舒服一些。数组初始化时初值应该尽量大,且dp[0] = 0。该题是完全背包,可以重复使用同一个物品。所以要求用最少的物品装满,这就要求。多重背包:n种物品,每个物品有多个。该题在递推公式部分和。
2025-04-19 19:04:16
156
原创 代码随想录day37完全背包
上述情况下背包已经满了那考虑放i的情况,就需要先把i的位置容量预留出来j-weight[i],当然预留出来容量的背包价值也要最大dp[i-1][j-weight[i]],再放入物品i,则背包j被装满的价值dp[i-1][j-weight] + value[i];,显然dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight] + value[i])总的来说,每个背包(容量由小到大)的价值不是由上一层状态转移来,而是同一层,容量较小的背包的状态转移来。上图截自代码随想录公众号。
2025-04-17 14:53:42
442
原创 代码随想录01背包完结
整体思想:每个元素的符号只能是+或者-,target就等于一部分数字的和减去另一部分数字的和,这样来看原数组就能拆分成两个组合part1和part2,设他们的和分别为left和right。递推公式:容量为i的背包没有放如物品j,dp[j-1][i],如果要放入j,至少要先预留出空间来将j放进去在加上j的重量(价值)数组含义:从物品0到物品j中任选使容量为i的背包可以装的最大重量dp[i]数组的含义:从j个物品中任选装满容量为i的背包的组合数量dp[i]初始化i = 0 容量为0,最大重量也为0。
2025-04-16 12:56:40
359
原创 代码随想录动态规划part03
由二维情况推断得到,这一层背包j的价值由上一层的容量小于或等于j背包价值转换而来,已经把上一层的值拷贝到这一层了,所以应该从后向前遍历这样上一个状态还没有被改变可以获得,从而转换到这个状态,背包:有n种物品每种物品只有一个,只能被用一次,不用管物品的重量是否相同,也不用管顺序。遍历顺序,画表格,依据递推公式来看,主要是看推出当前状态的前一个状态是否存在(有效):从物品0到物品i任取放进容量为j的背包里,使背包价值最大。当只放物品0,无论容量多大,价值=物品0的价值。完全背包:有n种物品,每种物品有无限个。
2025-04-15 15:57:19
403
原创 代码随想录动态规划part02
这里初始化错误了,想法是对的右一和下一初值都是1,起点不需要走所以是0,但是在遍历时从起点开始,将右一和下一都清空了,导致整个dp数组值全为0;拆分的第一个数字是j,还要对i-j继续拆,但是无论对i-j如何进行拆分,找到其对应的乘积最大值dp[i-j],然后*j就得到i在j拆分下的乘积最大值。递推公式:将i拆出来的第一个数j(j从1开始遍历),dp[i] = j*dp[i-j];举例说明若n=4,当j = 2,j*dp[j-i]=2*1=2,结果dp[4]=2。初始化dp[1] = 0, dp[2]=1。
2025-04-14 22:32:41
402
原创 代码随想录day32 动态规划(感觉又看到递归的影子)
首先dp[0]和dp[1]是0,那是出发点,且每次可以爬一层或者两层,就是说可以从倒数第三层和倒数第二层都可以到达顶层。总结:递推公式从底层一直向上推,好像递归到底层后逐步将值返回的过程。数组下标表示当前所在位置,数组长度代表顶层所在位置。支付费用cost[i],可向上爬1层或者两层,尝试从2个台阶推到3个台阶,从3到4。取他俩到达顶层所需要费用的最小值。爬一层支付的费用和到达。
2025-04-12 20:15:43
254
原创 代码训练营day31
如果中间某一位变成9了,为了满足条件后面的数值均为9才符合题意,所以用flag来标记位置,而不是遇到非递增数列就把较小数值变成9,将数字按位拆分为数组不如将数字转化成字符串去处理,因为返回的结果也是数字使用标准库函数来转换写法更简单。不要想着只把大的数值变小,当后一个数值比前一个数值小应该把后一个数值变为该位最大值,然后前一位-1。
2025-04-11 16:15:05
212
原创 代码随想录day30 贪心之重叠区间
升序排列,看第一个气球的直径区间能够与后面几个气球重叠;不重叠则弓箭数+1,从该气球处继续向下比较。按照end升序排列,如果end相同按照start升序排列,尽可能减少重叠的判断。要理解找到一个合格的子片段就舍弃他,从末尾的下一个位置开始就是下一个片段。利用哈希表存储每个字母出现的最后位置。将气球按照他们的最大直径。用最少数量的箭引爆气球。
2025-04-10 12:24:49
170
原创 代码随想录day29 贪心算法
/ 移动到插入位置。如果前面四个加油站作为起点都不满足条件,那么起点只能是最后一个加油站,每一个孩子都要和他的左右相邻孩子比较,比分数低的多,比分数高的少。那关键在于为什么遍历完数组,剩余量大于等于0就找到起点位置?既然一定可以跑一圈说明一定存在加油站可以作为起点。按照身高从高到低依次排列且相同身高k值大的靠后排。然后依次将身高较低的人排到队列中与k相等的下标处。逐个排除不符合条件的位置,下一个就是起点。记录已有的各种钞票的张数,分情况找零。还要注意加油站的油量是递增的。
2025-04-09 21:02:09
261
原创 代码训练营 day 26 贪心
除以上两种情况,在整个过程中prediff都不会在出现值为0的情况,因为他只记录上一个有效摆动的方向,所以当再出现摆动且方向相反时才会更新结果并更新prediff。摆动序列:连续两个数字之间的差值严格的在正负之间交替,两个相邻差值必须一正一负,不含有0;记录前两个元素的差值prediff和当前两个元素的差值curdiff,如果是异号说明计算当前差值的被减数是摆动的。先保留局部最大值,再去寻找剩下的和,进行比较,最后留下的就是全局最大值。每一个合适的饼干都有匹配的孩子,匹配完也就达到了全局最优。
2025-04-07 14:42:53
400
原创 代码训练营day25 回溯算法
考虑用一个集合来存储使用过的数值,如果在进行树层遍历时,如果当前元素存在于集合中,则跳过,遍历下一个元素(或者用一个数组,题目条件有给定数组的元素范围为-100~100共201个元素,用下标映射对应这些数值,下标0对应元素-100,下标200对应100,出现过就为1,没出现就为0,),,取极端条件原数组如果是递减序列,那么他就没有非递减子序列,结果为空,所以不能进行排序操作,因此,不能使用原本的树层去重方法,每一支都要遍历完所有元素,只是要把用过的元素标记出来,避免重复添加。回溯算法 part04。
2025-04-06 18:17:43
189
原创 代码训练营day24 回溯算法
左闭又闭,传入的是每ip地址中的每一段数字,所以要注意循环遍历的条件涵盖起始位置和终止位置)需要判断地址的每一段是否符合条件,任何一段不符合结束本层递归。单层递归逻辑:将给定数组的数值加入vec,并将vec存入结果。传入参数,修改后的字符串,起始位置,终止位置(起始位置不能大于终止位置,放置访问越界。终止条件:当层索引值==树的宽度结束。通过ascii码将字符转换成数字。实时更新插入‘.’的数量。整数值不能大于255(回溯算法part03。本题关键在于终止条件。插入3个’.’时判断。下层递归的位置i+2。
2025-04-06 18:15:26
273
原创 代码训练营day22
的组合,所以指针指向最多到当前位置,再继续遍历以及向下一层递归都是没有意义的,根据举的例子可知,出现最后一个符合条件的组合重复是因为,每次他前面的数字都会顺序递归一次,根据模板,考虑是在叶子处理问题,还是在每一个节点都要处理问题(子集)先执行的递归逻辑所以输出顺序是从最后一个符合条件的组合开始的。:抽象为树,集合大小确定树的宽度,递归深度确定树的深度。选择:本层集合中元素(树中节点的孩子数量是集合大小)字符串的长度:可进行组合字母的总数,以及组合的长度。组合中的每一个字母只来自于一个数字。
2025-04-02 22:21:15
748
原创 代码训练营day20 二叉树
其中第四点要考虑BST的特点可以将被删除节点的整个右子树嫁接到左子树的最右下角,或者将左子树嫁接到右子树的最左下角。上述方法是找到插入位置的上一个节点就插入,并且停止递归,因为题目条件保证了。返回的是被删除节点的左儿子,虽然是在右子树但是依旧符合搜索树的有序性。被删除左右儿子都存在,把右儿子嫁接到左儿子的最右下角。被删除的节点没有左儿子不用嫁接直接返回右儿子。返回的是被删除节点的左儿子重新构造树。寻找左儿子的最右下角的嫁接位置。最后别忘了把内存释放!空节点的祖先是其本身。空节点的祖先是其本身。
2025-03-31 13:26:40
798
原创 代码训练营 day18 今天又涉及回溯的思想
什么为前什么为后,按照中序遍历一个二叉搜索树,将其节点值顺序存入数组,前代表着较小的那个数值对应的节点,后代表他后一个数值代表的节点,所以不是以根为前,第三题看了卡哥的视频才写出来,递归问题考虑条件要全面,但是不能总去推理整个过程(太复杂,容易乱),所以单层逻辑就一定要抓住单层。的初值为整数最大值,每次计算两个节点之间的差值,如果差值小于。对于当前根来说,p,q分散在左右子树里,公共祖先就是本身。根节点是其左孩子的后一个节点,左孩子为前一个节点。如果p,q都在左,公共祖先为左儿子,反之为右儿子。
2025-03-29 14:33:10
880
原创 代码训练营day17 二叉搜索树
切割数组,对于划分出的任一数组,根节点为数组内最大值,最大值左侧子数组为左子树节点,右侧子数组为右子树节点。左儿子的值大于等于根的值或者左儿子的右儿子的值大于等于根的值。右儿子的值小于等于根的值或者右儿子的做儿子的值小于等于根的值。小于当前根节点值,且在左子树内又找不到匹配的节点,第一个。若左子树不空则左子树所有节点的数值均小于根节点的数值。若右子树不空则右子树所有节点的数值均大于根节点的数值。左儿子的值大于等于根的值或者右儿子的值小于等于根的值。找到最大值,还要记录最大值对应的下标,因为要切割。
2025-03-28 13:19:52
711
原创 代码训练营day16 递归啊递归
今天递归明白了好爽找树左下角的值题目链接文章讲解层序遍历intTreeNoderoot) {intres =0;int>> vec1;forinti =0;i < _size;qpop();
2025-03-27 13:17:37
895
原创 代码训练营day15 二叉树part03
只要是和高度有关的二叉树类题目,在写后序时首先看最底层的子树,看他的根节点和子节点的关系,因为他是递归的终点,如果他都不符合条件,前面一系列操作都是没有意义的。对于平衡二叉树的定义没有理解的透彻,对于树中的每一个节点他的左右子树高度差均不超过。完全二叉树的节点个数(优先掌握递归)确定返回类型和传入参数。高度:最大深度,后序。确定为叶子,终止递归。
2025-03-26 20:00:02
632
原创 自定义单调队列、优先级队列以及KMP算法应用
那么他的最小重复子串,就是他的前后缀最大相同子串的最大值(next数组中的最大值,字串的长度),就是对应此时前缀或者后缀不包含母串的那部分。判断是否是可重复字符串,母串的长度如果能整除,没被next数值最大值包括的那部分子串,则母串是能够由重复字串组成的,反之不行。将队列里的元素排序,方法就是把即将排队的元素和队尾的元素进行比较,大于就弹出这样队列里的元素就是单调递减的。窗口是必须要移动的,且窗口的大小是固定的,如果当前窗口已满是必须要将原来的头部元素移除的,然后选出最大值。
2025-03-23 19:51:34
653
原创 代码随想录day10 栈与队列
这道题便利的一点是在移除或者取栈顶元素时,队列都不为空。将头部的元素出最后一个外逐个移回队尾。将头部元素出最后一个外逐个移回队尾。栈不为空且栈顶元素等于当前字符。导入可能会破坏之前已有的元素。删除字符串中的所有相邻重复项。不知道在第七行为什么会报错。这题需要看讲解复习一下。将栈内元素拼接成字符串。正确的做法应该是,当。只有一个元素直接出栈。只有一个元素直接出栈。
2025-03-21 22:53:30
857
原创 代码训练营day7 哈希表 part02
454.四数相加II题目链接文章讲解两数之和的Plus版,方法一脉相承intint> mysum;//我自己明白的一点对于map的key存的是和,value的值存出现次数forinti =0;forinti =0;
2025-03-18 20:47:56
749
原创 代码训练营day6 哈希表 part 01
用时17min,卡在了一个低级错误,我最后判断部分遍历写成传入的两个字符串了。昨天休息日,理了一下数组和链表中的卡壳的地方,学习了时间复杂度的计算方法。结果中的每个元素是唯一的,考虑集合(存储一组不重复的元素)结果中的每个元素是唯一的,考虑集合(存储一组不重复的元素)是集合里已经出现过的元素说明开始循环了,此时标志位清。中的数字能在集合中找到,则添加到集合中。用数组将出现的字母存储到对应的位置。,但是系统要求的返回结果必须是数组。用两个数组来存储各字母出现的次数。时,如何停止循环返回结果。
2025-03-17 18:58:09
700
原创 代码训练营day 4 链表part02
所以终止条件不对,交换的条件是每次至少操作两个节点所以还要考虑cur -> next -> next。访问了空节点说明终止条件出问题,f->next为NULL,则f->next->next一定为空。指针1指向头节点,指针2指向相遇节点,二者每次向前移动一步,相遇节点即为入口节点。相交的概念是二者共享当前节点(值和地址)以及后续的节点。交换的条件是每次至少操作两个节点所以还要考虑。交换的条件是每次至少操作两个节点所以还要考虑。不修改内部值的情况下,两两交换相邻节点。如果当前处理的是链表最后的两个节点,
2025-03-15 18:12:39
455
原创 代码训练营day3 链表part01
前者是使tmp成为下一个节点及加入链表tmp的指针指向下一个为节点不知道是什么,后者是指针指向下一个节点没有改变链表但是可以引用其值。节点的下一个但是该虚拟头节点并没有被加入到当前的链表中,下一个节点可能为空也可能不存在。当在头部或者中间添加或者插入节点时既要顾前也要顾后,当前节点的指针域一定要指向下一个节点。之前是没有添加头节点,直接写的,写完感觉有点乱,就添加了一个虚拟头节点然后进行操作。还有一点是没有搞清楚两个指针的关系,pre始终是上一个顺序靠前的节点,并且要先移动。不要忘了原本的下一个节点。
2025-03-14 22:36:41
813
原创 代码训练营day 2 数组
今天做题大概用了4到5个小时,中间了解了一下前缀和用法,对于螺旋矩阵是一点思路都没有,所学习了一下卡哥的视频,然后自己研究了一下,算是吃透了。平心而论虽然做完了但是真正吃透的只有区间和以及螺旋矩阵,第一题和最后一题就是暴力解出来的,后面需要花时间好好研究一下,尤其是滑动窗口。一、长度最小的(连续)子数组题目链接:209. 长度最小的子数组 - 力扣(LeetCode)视频讲解:拿下滑动窗口! | LeetCode 209 长度最小的子数组_哔哩哔哩_bilibili提示:本题的关键在于理解滑动数组暴力
2025-03-13 21:03:28
379
原创 代码训练营day1 数组part01
关键是排序问题刚开始我只是单纯的用两个指针指向相邻的两个元素进行比较,然后交换位置,造成的问题就是遗漏了元素并且没有设置好循环条件,导致最后指针超出了数组的长度,结果返回一串莫名其妙的数字。第一遍做就是暴力,还多此一举以中间位置的元素将数组划分,然后去遍历得到目标元素的下标,花了33分钟,既没有使用二分法也不如直接去遍历得到结果。后面根据卡哥的资料认真看了一下二分法的思路然后重新按照左闭右开、左开右闭做了一遍,对这个题目还是没有什么感觉,后续还需要观看视频讲解。视频讲解:。
2025-03-12 12:44:57
269
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人