- 博客(240)
- 收藏
- 关注
原创 LeetCode116.按字典序排在最后的子串 -- 求字符串中的最大后缀子串
由于只需要比较后缀,因此对于每个后缀子串,我们只需要记录其起点即可,暴力的比较 n 个后缀子串时间复杂度为。是最大的子串,那么由于字典序的特性(字符串相同时,长度越长,字典序越大)中任意字符构成的子串都不可能是最大子串,从而,我们可以直接更新。)的形式,也即一定是从某个字符出发,一直到字符串的结尾。在所有回合结束后,找出盒子中 字典序最大的 字符串。中对应字符构成的后缀子串的。开始的后缀子串更大,我们还应该更新。中任意字符构成的后缀子串都是小于。构成的后缀子串都是大于对应。的限制,字符串的长度最大为。
2025-06-11 10:53:17
197
原创 LeetCode2845.统计趣味子数组的数目 -- 数学 | 模运算
*注意:**子数组是数组中的一个连续非空的元素序列。以整数形式表示并返回趣味子数组的数目。这样,我们就将问题转换为了,在一个。,我们可以用前缀和简化,也即满足。那么这下思路就简单了,遍历。满足下述条件,则称其为。请你找出并统计数组中。
2025-05-29 19:48:51
836
原创 在【非负数组】中利用【负号】表达特定含义
依然是通过负号表示哈希的语义,这里的哈希表示该数字有没有被处理过。,请你找出其中没有出现的最小的正整数。并且只使用常数级别额外空间的解决方案。的语义,也即实现哈希的效果。给你一个未排序的整数数组。请你实现时间复杂度为。
2025-05-11 17:19:02
141
原创 数字搬家 | 基于交换的思想 | O(N)+O(1)
这题有些难度,单纯的套模板无法解决问题了,我们需要对数字进行转换,将其视为图,严格来说是单链表。具体的看注释,这道题和之前的题目不同,前面的题目都是。所谓的数字搬家,又称为基于交换的思想,指的是对于。,请你找出其中没有出现的最小的正整数。的时空复杂度下实现排序的效果。的特性,可以帮助我们解决很多问题。中的数字,并以数组的形式返回结果。),可知至少存在一个重复的整数。只有 一个重复的整数 ,返回。范围内,不存在重复的数字,。的整数,并以数组形式返回。此时,如果有一个重复的数字。构成了一个环,重复的数字。
2025-05-11 16:25:02
192
原创 LeetCode92 反转链表 -- 思维 | 一次遍历
先找到需要反转的子链表的头节点和尾节点,反转子链表,修改指针关系。,可以将这三个链表节点依次插入到链表节点。节点,那么此时就是头插到一个新链表中。
2025-05-11 15:52:45
256
原创 2023天梯赛选拔赛1 -- 补题
这个数据范围是在太小了,所以说,如果你的算法时间复杂度太小,那么基本上肯定是错的。),我们可以选择一个数放到对应的篮子里。其实题目的数据范围就已经给足了暗示了。让我们求,四个篮子的最大期望之和。题目大致就是说,我们有四个篮子(),每次给我们四个数(篮子的大小是有限制的。
2025-04-06 09:22:24
914
原创 ACWing 4493 -- 思维题 & 并查集 & dfs
那么我们只需要先找出所有的连通块,然后判断每个连通块中的每条边的度数是否位。其中并查集最简单,代码最短,因此对于求连通块问题优先考虑并查集。就可以判断该点所在连通块是不是一个简单环了。这其实是对性质:简单环中每个点的度数为。依据性质:判断每个点的度数是否为2。判断每个点是否连了两条边。的另外一种表达形式。
2025-04-06 09:21:54
649
原创 AcWing 100 -- 差分 & 贪心
我们发现,我们每次要么修改一个数,要么修改两个数(一个加一,一个减一),因此,贪心的话,第一问就解决了!对于第一问,我们可以贪心的方式,在差分数组中,每次选取两个数,对一个数加一,对一个数减一。为什么说是边界情况呢?当我们修改的范围从头开始,也就是包括头时,我们会修改。对于第二问,我们前面不止一次提到过了,差分数组。由于修改整个数组毫无意义,并且我们希望修改的。开始),最少的操作次数,使得差分数组。我们前面对修改的划分也提到了,只有修改。当我们修改的范围包括尾时,我们会修改。的值就是最后数组的元素,那么。
2025-04-06 09:21:23
707
原创 AcWing 1024 -- 记忆化搜索
好的,我们已经解决了如何找到答案,但是题目中的点不是一次性全部给出的啊,难道每给一个点我们都需要遍历一次树来查找路经之和以及最长的分支长度吗?其实是不必的,我们可以保存之前查找过的信息,下次搜索时直接使用,所谓**“记忆化搜索”**。之后,有多个分支,我们必须回头走,但是,有一个分支我们是不需要回头走的,还记得前面说的吗,“每次送完外卖之后不必返回起点。出于贪心的角度,我们肯定希望不需要回头走的那个分支尽可能的长,这样我们少走的距离肯定更少。另外,需要送外卖的点是逐个添加,每添加一次都要算一次最短路。
2025-04-06 09:20:02
265
原创 AcWing 3305 -- 建图
当然,我们也可以不添加虚拟源点,而是模拟虚拟源点的第一趟遍历,将所有初始时给定的作物都加入队列中即可。值得注意的是,这里的边权并不是传统意义上的边权,它代指一个条件。最晚的那个出现的时间起,我们才可能杂交,否则少一个怎么杂交。题目给定了我们一些初始作物,要求我们求目标作物,经典的。可能不容易理解了,其实很简单,虽然我们可以通过作物。最短路应该是可以看出来的,但是对于给定的规则,作物。好了,现在我们已经建立了一个图,接下来该如下求解呢?可能还容易理解,因为我们建图的时候就是如此设置的。的条件,才能到达(与。
2025-04-06 09:18:29
828
原创 AcWing 3696 -- topsort & 贪心
如果成功,那么我们便成功确定了拓扑序。那么对于剩下的没有确定方向的边,我们按照拓扑序确定方向即可。此时,一定能构成有向无环图。题目说了,给定的图不一定联通,事实上,不联通并不影响拓扑序,如果多个点之间不联通,那么他们的拓扑序是任意的。,如果失败,说明无论剩下的无向边在怎么确定方向,都不可能无环。我根据题目给定的有向边做一次。思路其实真的非常简单。
2025-04-05 23:53:35
356
原创 ACWing 4480 -- 二分 & 双指针 & 思维
,就是直接找到每个居民左侧和右侧垃圾桶的位置,记录和当前居民的位置的差值和垃圾桶的位置,最后在比较一下判断那个更近就行了。由于题目给定垃圾桶的位置升序(即使无需我们也可以排序),很容易想到二分,我们只需要枚举每个居民,然后两次二分来分别找到左侧和右侧的垃圾桶的位置就可以了。由于右侧的那个垃圾桶是居民右侧位置最小的垃圾桶,那么该垃圾桶的前一个垃圾桶一定是居民左侧位置最大的垃圾桶(如果存在的话)。我们可以从二分的语句里面去观察:由于我们需要比较左侧垃圾桶和右侧垃圾桶到居民的距离那个更小。
2025-04-05 23:53:05
593
原创 ACWing 4481 -- 双端队列 & 贪心 & dp
我们可以贪心的上下走,尽量不左右走,这样当我们第一次走到某个点的时候,左右走的次数肯定是最少的,这时候如果都不合法,那么后面的点肯定也不合法了。这时候如果下一次合法的路径走到这个点的时候,就不会继续往下走(因为已经标记为走过了),因此我们就漏了一个点。我们可以从另一种角度考虑:让状态表示的是走到这个点所需的向右走的最少次数。如果我们先走不合法的路径,然后标记为走过了,并且表示为不合法。,遍历所有的点,只需要额外记录左右走的次数就可以了。的状态表示中,我们状态的结果是这个点是否合法。,现在走到了某一个点。
2025-04-05 23:52:21
871
原创 bfs判重的坑
中判重时,应优先在入队时进行判重,而不是在出队时进行判重,因为一个节点。,这就会导致其他节点出队且加入新节点的过程中,可能会重复加入多次节点。在入队到出队的过程中,可能需要先出队很多其他节点。占用的空间过大,最后可能有几个点。AC代码:在出队时判重。MLE代码:出队时判重。
2025-04-05 23:51:05
471
原创 BUG -- 线性筛素数
又因为,我们的比较符号是小于等于,这就导致下取整得到的结果我们取不到了!但是防止溢出却是是个好技巧,我们不能丢弃了,那怎么办呢?将乘法变为除法防止溢出。但其实,问题就出现在这里!此时小于上取整的结果,等价于小于等于下取整的结果。或者说,在判断时不要用小于,而是小于等于。除法,是可能不能整除的!看起来人畜无害的样子,甚至还在。因为下取整导致循环提前结束掉了!中,我们就会少判断了一些。
2025-04-05 23:50:30
291
原创 dfs剪枝(排除等效冗余)
我们用反证法:假设某个木棒的最后一段搜索失败了,存在解决方案。,我们用反证法:假设某个木棒的第一段搜索失败了,存在解决方案。的最后一段搜索失败了,但存在一种合法方案,那么肯定会存在。有限考虑分支较少的搜索方式,常见的比如从大到小排序。的第一段搜索失败了,但存在一种合法方案,那么。:排除等效的情况,本题就是很好的例子,稍后解释。的搜索顺序并不会影响答案,因此这与。的搜索顺序并不会影响答案,故矛盾。的一段成功,同理我们可以将。的最后一段,而交换木棒。的第一段搜索失败矛盾。的最后阶段成功,并且。
2025-04-05 23:49:29
654
原创 DP问题空间的优化
通过代码可以看出来:[消去维度方法]空间节省的更多,毕竟它直接把一维消去了;但是对于可能需要修改代码逻辑(例如枚举顺序)。[滚动数组方法]空间消耗是[消去维度方法]的两倍;但是它实现起来比较简单,只需要在所有用到层数那一维的地方加上& 1即可。
2025-04-05 23:48:57
234
原创 Floyd算法
Floyd可以正确处理有向图或带负权非回路的最短路径算法 同时也被用于计算有向图的传递闭包Floyd时间复杂度为N3空间复杂度为ON2。
2025-04-04 09:59:29
817
原创 Leetcode 117 -- 树 | bfs
指针,让它指向它的(同一层)右侧的节点,如果没有,指向 $NULL,(初始时全部指向。这题让求的就是让把二叉树中每行都串联起来,对于这道题来说最适合的就是。看到关于二叉树的问题,首先要想到关于二叉树的一些常见遍历方式,也就是一行一行的遍历,如下图所示。题目要求我们填充每个节点的。
2025-04-04 09:58:41
854
原创 Leetcode 15 -- 双指针
当一个数和前一个数相同的时候,如果前一个数没有选,我们说此时子集重复了。双指针(又称为快慢指针)可以将一个二重循环优化为一重,因此我们可以用双指针优化。参考回溯中树层去重的例子,当一个集合的子集相同的时候,后面就可能出现重复。这是因为不需要判断,因为当前的nums[i]是起点,之前的数肯定没选。我们可以以此枚举每一个点作为第一个数,从后面寻找第二个和第三个数。先不考虑重复的问题。从暴力出发,我们需要使用三重循环,会超速。对于数组循环的优化问题,双指针很常用。因此,我们的目标是消除重复的子集。
2025-04-04 09:58:26
180
原创 LC2610 自定义排序遇到的坑
不过我们其实可以发现,上面对 nums 进行排序的行为有些画蛇添足了,因此我们并没有让 nums 按照 cnt 排序的需求。事实上,我们可以直接利用 cnt 数组。进行排序,然后出现次数多的放在前面,出现次数少的放在后面,例如输入。全在前面),而是杂糅到一起了,也就是说,我们的。然后就可以遍历同一元素,依次加入每一行。相等时的情况,这里只需要稍微修改一下。为了解决这个问题,我们希望特殊处理。相同的不同元素,并没有合理排序。但实际上,对于该输入,输出。并没有按照我们希望的那样(进行了排序,但是对于。
2025-04-04 09:57:09
134
原创 LeetCode 5 -- 区间DP | 中心拓展算法
而马拉车算法能有效解决这两个问题,虽然它也是基于暴力匹配,但是它通过预处理做了优化,并且能避免偶数长度回文串的问题。,因此在中心拓展算法中,我们除了每次选取一个点作为中心外,还要选取两个相邻的点(前提是这两个点的值相同)作为中心处理回文串长度为偶数的情况。我们可以枚举字符串的每个点为中心,从这个点开始向两头拓展,如果拓展之后的两头边界仍然相同,说明是回文串,否则结束拓展。的时间复杂度级别是相同的,但是该算法的常数更小,每次拓展是拓展两个元素,而。另外,中心拓展算法无法直接解决字符串长度为偶数的情况,例如。
2025-04-04 09:56:37
973
原创 Leetcode 33 -- 二分查找 | 归约思想
一个清晰的思路:这道题和平常二分法查找的不同就在于,把一个有序递增的数组分成了,两个递增的数组,我们需要做的就是判断这个数在哪一个递增的数组中,然后再去用常规的二分法去解决。的角度去考虑二分问题,那么二分的过程就是不断归约的过程,而归约又与二叉树联系很密切。可能由两个有序区间构成,那么我们是否能找到这两个有序区间,然后分别在这两个区间上进行二分呢?未必有序,也就是这两个子区间未必都有序,但必然至少有一个是有序的。一个重要的性质:源数组经过旋转之后,会划分为两个递增的数组,我们假设为。是一个旋转数组,导致。
2025-04-04 09:55:50
891
原创 Leetcode 347 -- 优先队列的坑
函数并作为模板的比较类型传入这个类,因为类的成员函数必须被类的实例调用(静态成员函数除外),而在这里我们显然是没有类的实例的,所以说拿什么调用它呢?指针一般作为隐式的最左侧的操作数(第一操作数),因此我们只能显示的指定一个操作数。既然有了成员对象,自然也就有了指向他的。外面重载时,我们需要显示的指定这两个操作数,但是如果我们要在。会想你调用成员函数的方式,是不是必须得通过。其实上面的回答从另一方面论证了:我们不可以在重载类的。的运算符时,运算符的个数是要少一个的!在下面的例子中,我们虽然可以将。
2025-04-04 09:55:14
710
原创 Leetcode 135 -- 贪心 | 拓扑排序
第二次遍历就需要满足糖果比它右边的孩子多了(如果评分更高的话),但是这样还需要判断糖果是否本身就比右边的孩子多,如果本来就比你多的话,就不能变!题目要求很简单:如果一个人的评分比它左边的孩子要高,那么分得的糖果要比左边的孩子多。如果评分比它右边的孩子高,那么分得的糖果还要比它右边的孩子多,每个孩子至少一个糖果。如果一个孩子的评分比它相邻的孩子多的话,那么分得的糖果只能多一个,这样才能保证分得的糖果最少。我们可以遍历数组两次,第一次遍历满足每个孩子的糖果比它左边的孩子糖果多(如果评分更高的话)。
2025-04-04 09:55:08
189
原创 Leetcode 437 -- dfs | 前缀和
注意这个根节点是最顶层的根节点,而不是将每一个节点都视为根节点,因为我们只需要知道最顶层的根节点到每一个节点的前缀和就可以找到某一个节点到任意上层节点的前缀和,通过减法。另外,我们还需要记录某一个前缀和的个数,因为节点的值可能为。
2025-04-04 09:55:01
885
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人