自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 算法------(13)KMP

dp[i]的含义为[0,i-1]个字母可以分解,因此我们枚举每一个j,只要满足[0,j-1]时能分解且[j,i-1]也在P集合内即可。匹配用kmp,后续查找时的优化思路为对a中每一个下标数组,在b的下标数组二分查找第一个大于等于它的数,如果这个数存在则返回其与a中对应下标的差,和其前面一个与a中对应下标的差,如果满足则返回。对于模版中的j,我的理解是已经匹配了j个字符,因此next【i】还可以理解为对于已经匹配了i个字符的字符串来说,假如后续匹配不成立,则该字符串至少还有next【i】个字符是匹配的。

2024-03-01 09:07:15 1042

原创 算法------(12)Trie树(字典树)

对每一个节点,我们对应一个字符串的大根堆,每次访问这个节点时把当前字符串加入,并且如果该大根堆中字符串数目大于3时,将堆顶的字符串(字典序最大的那个)弹出。记n为字符串长度,我们对n([0,n-1])有两种划分方式,一种是把 s[n-1]当做额外字符,因此dp[n] = dp[n-1] + 1,另一种是查看[j,n-1]是否在字典中可查找到,如果可以则dp[n]又等于dp[j](相当于[j,n-1]已经处理好,只需要再处理[0,j-1])因此对每一个i枚举对应的j即可。对父子节点的关系还是不太清楚。

2024-02-23 19:30:44 884

原创 算法------(11)并查集

首先把每一个数的根节点设为其本身,然后对于每次输入的数,如果其根节点为本身,说明其第一次出现,因此把根节点更新为原先的根节点+1,否则查找其根节点(由于每次都加1,因此 从 其本身 到 其根节点-1 都已经出现过),然后输出根节点并且把 根节点+1 作为根节点的新父节点(这个父节点有可能还会有父节点,但并不影响,可以理解为两条链相连成为一条更长的新链)把每一个人的关系不好的人放入一个集合中,如果这个集合的人里面有人跟该人的根节点相同说明其属于同一个集合,不成立,反之则把他们加入同一个集合。

2024-02-09 11:08:51 952 1

原创 算法------(10)堆

由于堆本质上是一个完全二叉树,他的每个父节点的权值都小于左右子节点,而每个父节点编号为n时,左节点编号为2*n,右节点编号为2*n+1。假如一个数为丑数,那么这个数的两倍,三倍和五倍对应的数也是丑数,当然这么做肯定会有重复,因此我们用一个哈希集合来存储出现过的数,这样保证小根堆里面不出现重复的数,因此第k次取出来的数就是第k个丑数。由于优先队列只能访问队头数组,所以我们要让数据流中的第K大元素是优先队列的队头,因此我们要保证优先队列中只有K个数,这K个数中的最小的数就一定是第K大的数,也是优先队列的队头。

2024-01-25 17:30:08 396

原创 算法------(9)哈希表

已知一个数进行这个操作只可能有三种结果:(1)变得无限大(2)变为1(3)陷入循环,由于第一种情况总是会变成第二种/第三种情况(因为3位以上的数进行该操作都会变成3位数),因此第一种情况不会发生,我们只需要考虑第二和第三种情况。开放寻址法:一般来说开所需要的数字的3倍大小,首先对该数字取模,由于有负数存在因此要用(x%N+N)%N的方式,然后找某个数字在哈希表中的位置,不断对表进行循环查找,如果找到空位就存入,因此开放寻址可能存在多个位置存储同一个数且无法记录出现次数。这里只讲哈希表的做法。

2024-01-22 10:32:34 382

原创 算法------(8)二分

因此可以在每一个长度为1的左右端点为整数的区间内寻找解,如果两个端点的函数值一正一负则必有一个解。不考虑右端点的原因是两次相邻循环会重复计入,因此只用考虑一个端点即可(除了100.0以外的每一个端点都会成为左端点,因此要对100.0进行特判,不过洛谷数据太水了)。二分最大值的可能值,左端点是该序列的最大值,右端点是数组总和,这个区间就包含了所有可能的结果。二分右端点起始为1e10,因为设备最多有1e5个,假设每个设备的每秒消耗为1,而充电速度为1e5-1,则每秒会少1e-5的电,因此时间最长就是1e10。

2024-01-18 13:16:34 343 1

原创 算法------(7)高精度

乘法的过程可以分为:(1) 一个乘数的每一位乘以另一个乘数(2)每乘一次,进一位。(3)得到的每一个分位乘法的结果进行加法。加法的流程是:(1)每一位上的两个数相加(2)进位。因此用两个动态数组把A,B的每一位存下来,然后每一位相加并且进位。首先需要比较被减数和减数的大小,我们首先必须要用大数减小数(更为方便),因此需要有一个判断,先比较字符串长度再从前往后(动态数组从后往前)比较每一位的大小。如果减不够就向前要一位。除法本身的过程就是从高到低每一位除以除数,然后剩下的就借给下一位,最后还剩下的就是余数。

2024-01-13 23:28:29 375 1

原创 算法------(6)差分

在差分过程中,由于温度的范围较大但温度的个数较少,而我们并不关心温度的具体值是什么,只关心温度间的相对大小。为了使次数最少,我们一定会先把正的和负的同时消去,然后再把多余的正的/负的与a[0]消去,这样就可以得到从第二个下标开始全部为0的结果。本题的题面翻译存在问题,并不保证b奶牛的高度一定大于等于a奶牛的高度,只能确定a奶牛和b奶牛中间的所有奶牛的高度都要比a,b奶牛小。第一次差分是针对每一个操作做多少次的数组,每一个区间加1次,第二次差分是针对操作,每一个区间加操作次数*每一次操作加的数。

2024-01-11 18:51:53 348

原创 算法------(5)前缀和

一开始用的暴力法,直接T,然后学习了一下,假如S[i]%k==t,s[j]%k==t,则s[i]-s[j] %k==0.,因此我们只要记录有多少个前缀和 与 当前前缀和 mod k 相同,就可以求出来有多少段区间是k的倍数,同时,0 mod k 还是0,因此需要预处理一下。要求l,r区间内的和,就是求1,r区间内的和减掉1,l-1区间内的和,因此可以预处理出1到n中每个区间的和,然后以O(1)速度进行计算。跟上一题差不多,唯一的区别是需要利用map记录前缀和的下标,保证区间长度大于2。

2024-01-07 11:49:59 327 1

原创 算法------(4)双指针

两个链表可能具有相同的一部分,因此可以利用双指针,一个指针遍历一个链表,遍历完就到另一个链表接着遍历,可以证明其一定会在重合节点相遇,本质原因是在重合节点前pa走了一个pa的长加pb到重合节点的长,也就是pa到第一个重合节点的长+pb到第一个重合节点的长+重合节点的总长。学习了一下,本质上就是用两个双指针,一个用来指向目前不重复元素在前面已经排到的位置,另一个用来遍历数组,如果遍历数组指针指向的元素不等于前面已经排上队的不重复元素,则在已排上队的不重复元素后面放这个不重复的新元素,直到遍历结束。

2024-01-05 20:13:11 914 1

原创 算法------(3)位运算

一个需要仔细思考的题。lowbit法可以找出某个数的二进制表示中是1的最低位,方法是用x&(-x),由于-x又是~x+1(正数的补码是其对应的负数),而~x后,在x的最低位1后面的所有0位都会变成1,而这位1会变成0,此时再加1后,后面的1因为进位又变回了0,而这个1前面都是取反的,因此x&-x得到的结果就是从1开始后面跟对应个数个0,也就是2的n次方(n代表最低位的1在二进制数从右往左的第几位)。每一个二进制数的1的个数,都是其左移一位之后的二进制数的1的个数,加上其最低位的数(如果其为1)。

2024-01-01 18:48:49 920

原创 LeetCode精选算法200题------(9)246. 中心对称数

本来以为是最简单的方法了,然后看了眼题解才发现天真了。利用差分,进来的时候+1,出去的时候-1,然后遍历,如果连续两次进入就说明重叠了,,,,结果这个方法更慢。思考:本来以为是个贪心。按照左端点排序,遍历区间,如果存在一个区间的左端点比前一个区间的右端点小则返回false。还算比较高质量的题目。主要是这个方法我没想到过。

2023-12-29 23:05:24 400 1

原创 LeetCode精选算法200题------(8)246. 中心对称数

思考:用哈希表记录翻转前后对应的数。然后利用双指针头尾同时遍历字符串,如果遇到不在哈希表里的字符或者是在但两个翻转后并不对应(主要原因是这里所有都是一一对应或对应其本身的,不存在一个环的情况)则直接返回false。学习:没找到什么好的办法,唯一的优化可能是把不包含在哈希表的数存入哈希表,这样不用count函数似乎可能可以快一点?不过本来就是100%。跟之前的易混淆数异曲同工吧。

2023-12-29 22:42:02 367 1

原创 算法------(2)离散化

把每个起火点坐标离散化到一个小范围内,因为每个起火点的左端点一定小于右端点,因此假如有的左端点小于该区间的右端点,则两个左端点之间的区间也一定会被点燃。这个离散化的想法非常特别,把每个坐标离散化之后,直接把大矩形分割成一个个小的矩形,然后判断这些小矩形是否包含在这些矩形内,如果满足对应条件则加上这一块的面积。用一个数组储存原来的数组元素,另一个排序,然后遍历原数组,二分查找其在排序去重数组中对应的下标。二分的本质是查找比某一个元素大于/等于的元素的下标,而在这里本质上就是查找这个元素在数组里排序后的下标。

2023-12-29 22:32:51 459 1

原创 LeetCode精选算法200题------(7)1271. 十六进制魔术数字

把十进制强转为十六进制之后取每位判断下是0-15中的哪一个,如果碰到了2-9就直接返回error,否则把对应字符转成对应字母,利用string类的“+”得到结果,当然,这个结果需要利用reverse反转,因为每次得到的位数会放在最后,因此第一位实际上在字符串的最后一位。就是利用stringstream啦,可以通过读入流里的字符串来直接获得16进制的数字,但是此时需要注意字符串里的数字为小写,因此还要转为大写,其次是这个代码也可以不用“+”,而是直接用下标进行循环。学习:法1:10进制快速转16进制的方式。

2023-12-27 16:47:38 302 1

原创 算法------(1)区间合并

其实还可以利用dp来做,用f(i)表示前i个区间里能选出的最大的不重复区间数,则可以分为倒数第二个选第1个区间,第2个区间。(注意,一开始是每个都只选自己,因此每一个i的值都是1。解法是将所有区间按照左端点排序,然后从第一个区间开始依次遍历,如果该区间的左端点大于合现存合并区间的右端点,则将现存合并区间存入vector并将该区间作为新的现存合并区间,否则将两个区间合并作为新的现存合并区间。只不过这次合并时现存合并区间的右端点应该取ed和r两者最小,因为要求的是几个区间的共同交集而不是几个区间交集的并集。

2023-12-26 15:04:01 862 1

原创 LeetCode精选算法200题------(6)1064. 易混淆数

然后利用vector存题目数字的每一位,如果这一位在哈希表中找不到则直接返回false。得到的结果一定是所有数字都可以翻转的数。双指针把vector遍历一遍,如果头翻转的数和现在的尾不同,则return true,如果没有不相同则说明这个数翻转后和原来一模一样,则return false。学习:没有找到什么更好的优化。绝大部分题解是把翻转的数字求出再和原数字比较,反而慢了?不知道有没有大佬有更好的题解。思考:用哈希表记录每个能旋转的数,旋转后的数是什么,达到每次访问时O(1)级别的速度。

2023-12-26 10:17:58 355 3

原创 LeetCode精选算法200题------(5)1064. 不动点

(2)upper_bound返回的是迭代器(类似于指针),因此需要用vector::iterator来记录该迭代器,但是迭代器解引用之后是该对应元素的值而非该元素的下标,因此需要利用distance函数,distance可以返回两个迭代器之间的距离。思考:最简单的办法就是遍历一遍数组,O(n),顺便优化下细节,当时不知道怎么想的,从后往前遍历了,然后遍历到最后一个数组元素大于0的地方结束,如果相同返回值,不同返回-1。简单直白,但是并不是题目所要的解法。一个思路算法都比较简单的题。

2023-12-26 09:48:45 413 1

原创 LeetCode精选算法200题------(4)359. 日志速率限制器

思考:用时间轴的方式进行思考。将每个字符串和其出现的时间用哈希表储存,每次遇到该字符串时先判断是否为第一次出现,是则储存,不是则判断其最后一次发送的时间戳+10s与当前时间的大小,如果大于则无法发送,返回false,否则返回true并更新最后一次发送的时间戳。原本的代码将message是否插入单独列为一种情况进行讨论,事实上这么做增加了时间消耗,无论message是否存在都可以进行判断,只需要改变记录的时间为下一次可以出现的时间而非上次出现的时间,这样做便可以把两者合并,事实上应该也是最快的方式。

2023-12-25 19:22:49 479

原创 LeetCode精选算法200题------(3)1086. 前五科的均分

写的时候遇到了许多问题。记录一下map的注意点:(1)emplace比insert更快(2)map自动按照key排序,unordered——map 哈希表无序(map本质是红黑树)(3)遍历map可以用auto[a1,a2],好像也可以直接first,second但是leetcode好像不行。可以用map

2023-12-24 21:00:21 481

原创 LeetCode精选算法200题------(2)408.有效单词缩写

遍历时分两种情况:1)abbr的指针对应的字符不是数字,则两个指针都往前走。2)abbr的指针对应的字符是数字,则再分情况讨论:1)数字为0,则必然是前导0,直接return false。2)数字不为0,把对应的数字用x保存,如果大于word字符串剩下的字母数则return false,否则比较 word指针加上x后对应的字符 和 abbr指针在碰到数字后碰到的第一个不是数字的字符 是否相同。同时每一次abbr的字符为字母时,将其与目前的word字符串对应位置的字母进行比较,不相同为false。

2023-12-23 20:31:01 501

原创 LeetCode精选算法200题------(1)266.回文排列

偶数长度的字符串不能存在任何出现次数为奇数的字符,奇数长度的字符串不能存在大于一个出现次数为奇数次的字符。(因为偶数长度的字符串,出现次数为奇数的字符必然成对出现,因此两种情况都可以用cnt

2023-12-22 21:09:54 961

空空如也

空空如也

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

TA关注的人

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