自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(21)
  • 问答 (1)
  • 收藏
  • 关注

原创 代码随想录算法训练营第四十一天

这就代表着节点的值等于节点在节点序列的位置,也就是说,假设当前的节点值为i,那节点之前一定有i - 1个节点并且值比 i 小,节点之后一定有n - i个节点并且值比i大。由于第一步拆分可以拆分成两个数字,例如3拆分成2,1,那么以此为基础,我们可以去讨论拆分出的数要不要继续拆分的问题,继续拆分的依据就是拆分后的乘积比不拆分时的大。现在用结果来比较,不继续拆分的话结果是2,继续拆分的话结果是1,显然不继续拆分得到的结果更大,所以把这个更大的值保留,不需要继续拆分了,因为后面肯定是越拆分乘积越小的。

2023-11-21 19:11:07 31

原创 代码随想录算法训练营第三十九天

实际上,只要有一个位置有障碍物,之后的路线就走不下去了,也就是说,后面的dp数组元素的值都必须是0。那么如何初始化,试设想,如果机器人从起点一直往右走,或者一直往下走,都只有一种走法,也就是说我们可以把第一行和第一列元素的值都初始化成1,因为这样初始化恰好也能满足递推公式的赋值。这道题目大体思路和上一道题目差不多,只是多了一个条件,就是网格中含有障碍物,如果dp数组元素的位置对应的网格的位置含有障碍物,应该如何操作?障碍物的限制条件影响到了两个过程,一个是初始化的过程,一个是递推的过程。

2023-11-18 17:44:59 633 1

原创 代码随想录算法训练营第三十八天

那么dp数组就可以用来存储到达每一个台阶有多少种方法,i即代表第几个台阶,由于在每个台阶上我可以选择向上走1步还是2步,所以能够一步走到当前台阶的,只能是当前台阶的上一个台阶和上上个台阶,而一步走到当前台阶不算另外的方法,所以递推公式。可以确定dp数组存的就是到达每一个台阶的最低花费,再根据上一题爬楼梯的递推公式,所以最低花费只需要考虑上上个台阶和上个台阶的最低花费加上它们向上爬楼梯的花费取最小值即可。,再根据题意,可以知道dp数组的下标表示第几位的斐波那契数,dp数组存储的是整个斐波那契数列。

2023-11-17 18:40:09 42

原创 代码随想录算法训练营第三十七天

题目要求的是不大于给定数值的最大单调递增数字,如果当前位数不满足单调递增,例如332,遍历到2,2不满足>=3,这个时候要求的数字的个位数必须小于2,并且保证递增要大于3,这明显是不可能的,对于332的后两位来说,这个数字一定不能超过30,于是便是29,即前一个位数减1,记录下当前数字(2)的位置。思路:从后往前逐位判断相对前一位是否单调递增,如果不满足单调递增条件,就将前一位数值减一,并记录下当前数字的位置,随着for循环不断更新不满足单调递增条件的位置。为什么要记录下当前遍历数字的位置?

2023-11-16 21:06:03 30 1

原创 代码随想录算法训练营第三十六天

根据题意,每个字母必须在同一个字母区间内出现,假设第一个字母为a,最后出现的位置为8,下一个字母为b,最后出现的位置为9,那就必须遍历到9,不然b就会出现在下一个字母区间。将每个区间按照从小到大的顺序排列好之后,位置靠前的区间,它的区间起点一定靠前,也就是说,靠前区间的起点始终包含靠后区间的起点。此时如果两个区间要重叠,那一定是后面区间的起点小于前面区间的终点。思路:按照左边界排序,然后逐一比较是否是重叠区间,如果本区间与前面的区间重叠,那就应该删除前面的区间,所以把要删除的区间数加一,并更新重叠区间。

2023-11-16 18:47:59 19 1

原创 代码随想录算法训练营第三十五天

仔细对比一下不难发现,两段代码的答题思路是一样的,先按照第一个元素的值排序,这样的话就不要去判断左边界是否有重叠部分,因为靠后的左边界一定是包含在靠前的左边界之前的,然后再去找重叠区间 ,只要当前气球的右区间大于或等于下一个气球大小的左区间,那么两个气球一定有重合区间,于是需要记录这个重叠区间去跟后面的气球比较,怎么记录这个区间?很简单,只需要找前后两个气球有边界的最小值就是重合区间的右边界,因为是前后的顺序比较,每次只需要把重合区间右边界的值赋给下一个元素的右边界就搞定了。以下是正确的能够通过的题解。

2023-11-14 19:56:14 19 1

原创 代码随想录算法训练营第三十四天

而是遍历一次数组就行了。本题的思路是,从加油站1开始,每经过一个加油站更新当前汽油的剩余值,这个剩余值就是当前加油站加的油减去跑到这个加油站消耗的油,如果汽油的剩余值小于0,就证明以当前加油站之前的加油站作为起点都不行,所以起点更新为当前加油站的下一个加油站。排序之后涉及到两次贪心,第一次是把小的负数优先替换成正数,第二次是负数全部替换完之后k还不为0,也就是还有替换次数,那就去替换绝对值最小的数,因为即使它最后变成了负数,对总和的影响也是最小的。给定一个数组,通过替换k次数字的符号,来达到数组总和最大。

2023-11-13 21:05:29 16

原创 代码随想录算法训练营第十四天 104.二叉树的最大深度 (优先掌握递归) 111.二叉树的最小深度 (优先掌握递归) 222.完全二叉树的节点个数(优先掌握递归)

方法上是一样的,都是后序遍历,在上面二叉树的题解可以发现,我定义了两个变量leftmax,rightmax来存左右子树的最大深度,那对于N叉树是否需要写多个变量,或者说统计一下每个节点孩子的数量,都不用。这两个概念看起来没什么区别,其实可以结合向量的知识来理解,这两个概念的起点和终点互换了,也就是说,计算高度的时候,以叶子结点的高度为一,而计算深度的时候,以根节点的深度为一。特殊情况无非两种,一种是左孩子为空,右孩子不空,一种是右孩子为空,左孩子不空,任何一个孩子是空的,那只需要取另外一边的深度加上就行。

2023-10-26 20:56:29 24

原创 代码随想录算法训练营第十三天 层序遍历 226.翻转二叉树 (优先掌握递归) 101. 对称二叉树 (优先掌握递归)

这题有点难理解的,一开始我想用层序遍历再用双指针遍历每一层的结果,后来发现,这个方法只能判断节点的值是否对称,并不能判断节点的位置是否对称。此题可以用前序遍历比较左子树根节点的左孩子和右孩子是否和右子树的右孩子和左孩子相等,再利用返回的结果判断两个结果是否都为true。左孩子的值和右孩子的值不相等。右孩子为空,左孩子不为空。左孩子为空,右孩子也为空。上面这十道题都可以用层序遍历的模版来做,无非就是在遍历的时候。边界条件:左孩子为空,右孩子不为空。挺简单的,前序遍历翻转左右孩子。

2023-10-25 20:58:52 19

原创 代码随想录算法训练营第十二天 144.二叉树的前序遍历 94.二叉树的中序遍历 145.二叉树的后序遍历

非递归/迭代写法:前序遍历的遍历顺序和元素的处理顺序相一致,就是说,前序遍历遍历到那个节点,那个节点就出栈,并把左右孩子入栈。后序遍历可以由前序遍历的遍历序列得到,先把中右左,变成中左右(步骤),这样才能得到序列中右左,再把得到的序列倒置,就变成了左右中的后序遍历序列。中序遍历的写法与上面两种写法不同,因为中序遍历的顺序和处理的顺序没有关系,所以要用另外一个逻辑来处理,先不断遍历左子树直到左子树为空,然后在栈内弹出栈顶节点并访问该节点的右子树。144.二叉树的前序遍历。145.二叉树的后序遍历。

2023-10-25 17:14:42 21

原创 代码随想录算法训练营第十一天 239. 滑动窗口最大值 347.前 K 个高频元素

思路上还是很复杂的,因为这题的解法是要自定义一个单调减队列,也就是说,如果入队的时候前面有比当前入队的值小的数,都要出队,考虑到不可能队列里的元素都比当前入队的元素的值要小,所以这个时候出队必须要从队尾出,当然由于是滑动窗口所以队列中的最大值有被弹出的可能,所以还是要保留队头出队的功能。用双端队列可以很好地解决这个问题,因为双端队列就是从队列两端出队的。这道题的思路其实不难,用map将数组中所有元素以及出现次数都记录下来,然后把这些数据,导入另一种自带排序功能的容器,排一下序找前k个就行。

2023-10-23 19:40:06 25 1

原创 代码随想录算法训练营第十天 | 20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰表达式求值

但是,左右括号数量不匹配其实是两种情况 ,因为在用栈来解决这类符号匹配问题的时候,如果左边括号(例如“{”)数量比右边(例如“}”)的多,那就会出现明明已经遍历完了整个字符串,但是栈内还是有元素,如果右边括号数量比左边的多,就会出现正准备匹配的时候,发现栈空了,没有元素给右边的括号匹配。遍历完之后,栈内的元素就是处理好了之后字符串的所有元素,因为我已经记录下了所有的元素,所以可以直接给字符串缩容,并且从字符串末尾开始赋值,因为栈是后进先出的。当然,判断相等之前要判断是否栈空,不然就涉及访问空栈的异常。

2023-10-21 16:07:23 61 1

原创 代码随想录算法训练营第九天 | 232.用栈实现队列 225. 用队列实现栈

书接上回,在用栈实现队列的题目中,我提到了栈的灵活性更低,而且无法改变元素的顺序,所以必须要另一个栈来协助,但是这题不一样,当我们用队列来实现栈的时候,我们可以改变队列中元素的顺序,让新入队的元素放到队头,这样就可以实现一个栈了。在push函数中,我在将新元素加入队列之前获取了队列的长度,也就是加入新元素之前队列中元素的个数,当加入新元素后,我只需要将加入前每个元素,先出队在入队,这样先进的元素就可以被放在队尾,而新加入的元素就会在队头。

2023-10-20 19:41:31 26 1

原创 代码随想录算法训练营第八天 | 28. 实现 strStr() 459.重复的子字符串

KMP算法:用到了KMP算法的思想,并没有真的去匹配字符串,只是初始化了字符串的next数组,核心思想是一个能用重复子串表示的字符串,它的最长前后缀没有重合的部分,就是最小的重复单位。移动匹配法:核心思想是能用重复子串表示的字符串,它的前半部分和后半部分一定是相等的,这里的相等其实前半部分和后半部分可以重合,也不需要去拆分,只需要把两个字符串拼在一起去掉头尾,一定能在这个新的字符串里面找到原来的字符串。几句话是说不清楚的,还是多看几遍视频讲解来的直接。题意:找出字符串中第一个匹配项的下标。

2023-10-19 19:45:10 25

原创 代码随想录算法训练营第七天 | 344.反转字符串 541. 反转字符串II 剑指Offer 05.替换空格 151.翻转字符串里的单词 剑指Offer58-II.左旋转字符串

于是乎,循环里进行i++的操作就太多余了,每次将i加2k就足够解决问题。它要求把一个空格转成三个字符,可是给定的字符串就这么大(不讨论创建一个新字符串的方法),所以还涉及到扩容的问题,不仅如此,扩容之后还要把所有字符重新排列,因为扩容之后,原来的最后一位就不是最后一位了,每个字符的位置都改变了。我一开始在循环里直接i++了,然后又定义了一个count来计数,然后就是各种条件的判断,这样的话,其实有太多细节需要想清楚的,有一个地方没想清楚,就会出问题,我就是这种方法,想了很久细节,还是通过不了。

2023-10-18 18:51:06 74

原创 代码随想录算法训练营第六天 | 454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

今天时间有点赶了,过几天再回来补思路和感想。454.四数相加II。

2023-10-17 21:16:20 32

原创 代码随想录算法训练营第五天 | 242.有效的字母异位词 349. 两个数组的交集 202. 快乐数 1. 两数之和

其二,题解在检验字符串t的时候,直接将对应的位置减减,hash[t[j]-'a']--,这样的好处是,不用定义新的变量来统计字符串t对应字母的出现次数,而是最后直接判断哈希数组每个位置是否等于零,来确定字母出现次数是否相等。这道题的大致思路就是,建立一个能包含26个英文字母的哈希数组, 先遍历第一个字符串,将出现的字母和次数都记录在哈希数组里,再遍历第二个字符串判断其中的字母是否在哈希数组中有记录,次数是否相同。承接了上一题题解的思想,因为这道题数组的最大长度1000,范围不是很大,也可以用哈希数组解决。

2023-10-16 19:46:30 29 1

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

想到了用三个指针来实现,但是出错点在于,我把三个指针都写到了while循环的外面,感觉这还好,但是提交之后发现超时了,后来对比了一下代码随想录的代码,发现有两个地方不一样。这是仿照代码随想录的方法写的算法,大概思想就是,快指针和慢指针形成一个n+1的区间,当快指针指向空时,慢指针的下一个节点正好就是倒数第n个节点。这道题目卡的时间最久,我一开始的思路是,先求出链表总长度,再用总长度减去n,就可以把问题巧妙地转变为删除链表的第n个节点。状态:用暴力的方法写出来的。文档讲解:​​​​​​​。

2023-10-14 19:07:39 22 1

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

发现忽略了移除头结点的情况,因为移除头结点和移除中间结点的代码不一样,移除头结点的逻辑是head = head->next,即头结点直接向后平移,而移除中间结点的的逻辑是cur->next = cur->next->next。看完视频后,顺着思路,写了双指针法版本和递归版本,递归版本可以对着双指针法的代码去理解,特别是在pre和cur移动的部分,真的太好懂了。这样一来,就可以在这个题目的链表中,插入一个虚拟头结点,这样做的好处是可以使移除链表的逻辑统一,进而实现代码的统一。状态:会写方法不会定义。

2023-10-13 21:29:01 84

原创 代码随想录算法训练营第二天 | 977.有序数组的平方 209.长度最小的子数组 59.螺旋矩阵II

其实看完题目大体思路是可以想到的,给了一个非递减的数组,其中可能含有负数,让你返回平方后非递减的数组,那原数组的头和尾中的数平方后肯定有最大的数(因为可能含有负数),只要从头和尾开始找就可以了。我一开始想的也是设置了头尾两个指针,当检测到头部指针指向元素的平方大于尾部指针指向元素的平方就交换头尾,以为这样就可以保证后面几位都是最大且递增的,但是这样想是完全错误的,只能应付少数用例。例如,这道题目中,每一个for循环都不处理该行/列的最后一个元素,让下一个for循环接上处理,这种遍历方法是不变的;

2023-10-12 20:09:22 276

原创 代码随想录算法训练营第一天 | 704. 二分查找 27. 移除元素

仔细看题目,在移除元素的过程中,是可以改变原来数组元素的相对位置的,于是我就设置了头尾两个指针,当下标为left的数组元素与目标值相等,就交换left和right下标所对应的元素,然后再把right值减一,因为right始终对应着待检查数组的最后一个元素,不能保证right下标对应的元素的值与目标值不等,所以要--left重新检查交换过的元素。最后又看了解析,试着写了双指针(快慢指针法),这个方法主要弄清慢指针指向的是不含val的数组的下一个元素,而快指针指向的是待寻找(是否符合要求)的元素。

2023-10-11 16:18:40 553

空空如也

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

TA关注的人

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