![](https://img-blog.csdnimg.cn/20201014180756918.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
leetcode热题100
小小皮卡丘啃算法
这个作者很懒,什么都没留下…
展开
-
128.最长连续序列
解决本个问题的关键在于,找到一个数num,要求该数-1 (即,num - 1)在set中,再找到这组元素的最大数字,然后进行“串麻花”,将连续数字串起来,并且计数。题目要求时间复杂度为O(n), 所以需要使用hash表。但是由于只需要存储单列数据,因此使用hashset即可。set的特点在于:元素无序、唯一、可以包含空元素。在python中只需要调用set()即可,在java中Set set = new HashSet原创 2024-05-25 13:39:19 · 191 阅读 · 0 评论 -
138.随机链表的复制
所以复制后的链表有两个部分:原始节点(其random关系保持不变,但是每个原始节点的next都指向该节点的copy节点) + copy节点(copy节点与copy节点之间的random关系和原始链表保持一致,只是每个copy节点的next指向该原始节点的next节点)并且next指向都是 原始节点--->copy节点---->原始节点的关系,就是next指向next.next。也就是说,在每一个节点后复制生成一个新节点,该新节点的next指向下一个原始节点next的新节点;原创 2024-04-16 16:34:05 · 217 阅读 · 0 评论 -
41.缺失的第一个正数
2.利用数字和下标的关系。将数字大小-1与下标位置相对应。满足交换条件的数字大小为,在所需要范围内、与坐标不对应因此需要交换。3.时间复杂度在交换时候的优化。涉及到两个数字的交换,有可能出现一个是满足坐标要求,而另外一个不满足,因此判断条件涉及两个。如果交换完还是不符合坐标数字要求,则返回缺失。1.我们所需要排查的数字范围为[1,len(nums)]。·解题思路——要求时间复杂度O(n),空间复杂度O(1)————只涉及两个循环————原创 2024-04-16 11:33:08 · 218 阅读 · 0 评论 -
76.最小覆盖子串
这里表示,当滑动窗口中字符个数小于或等于所需要个数的时候,所需要的target_num 减一。这是因为该语句end] in need的条件下,也就是说,现在所放入的是s[end]一定是need中的字符,所以num可以减一。结束时候的判断条件就变为了,windows[s[star]] >= need[s[star]],这是因为,移动左窗口的时候,会导致所需要的元素滑出,从而影响所需要的target_num。当满足所需要求的时候,再考虑滑动窗口的左端,缩短窗口长度,获取最小窗口。————两个注意的点————原创 2024-04-16 10:12:55 · 164 阅读 · 0 评论 -
239.滑动窗口的最大值
2.循环窗口的长度为k, 也就是两个指标,i,和j(i表示开端,就表示末端)。—滑动窗口,如果左端滑出的值为q队列中的最大值,那么需要在滑动后将队列左端的数值弹出。—如果队列存在,并且窗口的值大于队列末端值,将队列的末端数值弹出。—当窗口左端的指标从0 开始的时候,就可以向结果数组中添加q队列的初始值。1.创建一个非增双端队列(使用collection),用来存放最大值。原创 2024-04-13 21:07:40 · 221 阅读 · 0 评论 -
42.接雨水
由于顺序变化了,所以每一个位置的rightmax都是由后一个位置的rightmax和该位置的height决定。每一个位置的eftmax都由前一个位置的leftmax和该位置的实际高度的最大值决定。3.再次遍历数组,每一个位置的装水量就是 leftmax和rightmax的最小值 载减去原位置的height。4.在移动的时候,由于指针式动态的,所以需要每次记录当前位置可以装的水量。——————动态规划涉及两个新数组,对此利用双指针改进————————————动态规划——————————单调栈————原创 2024-04-09 16:38:28 · 172 阅读 · 0 评论 -
24.两两交换链表中的结点
3.注意的点在于,要避免形成环链表。因此还是用了一个post指针,用来存放point.next.next的地址,再将point.next.next指向point,避免形成环链表,并且保证了交换的相对位置。2.在原始链表中使用指针point,先将point后一个结点挂上cur,再挂上point结点。然后point一次移动两步。1.创建一个虚拟结点,用来挂上交换后的结果。原创 2024-04-07 21:22:35 · 193 阅读 · 0 评论 -
19.删除链表的倒数第N个节点
5.当移除结点为尾结点时,判断条件fast.next is None and slow.next is fast,此时只需要把slow.next指向None 即可。利用快慢指针,慢指针比快指针晚出发n步。当快指针到达链表的末尾时候,慢指针正好到达要删除的元素的前一个结点,然后删除下位置结点即可。3.当移除结点为头结点,判断条件 fast is None and slow is head,此时只需要返回head.next即可。2.当n==0 时候,慢指针的位置为头结点的位置。————注意点————原创 2024-04-07 20:25:11 · 108 阅读 · 0 评论 -
2.两数相加
3.获取余数和进位数。将余数的数值生成节点,挂到cur上,并且更新进位数。2.两个指针分别指向两个链表,获取对应节点的val,进行相加。4.判断最末尾是否有进位数,将进位数生成节点,挂到cur上。为了减少运行时间和运行的内存消耗,精简代码。1.创建一个虚拟节点用来存放产生的结果。原创 2024-04-07 14:58:21 · 216 阅读 · 0 评论 -
21.合并两个有序链表
2.两个指针分别在list1 和 list2 中移动,比较指针的val至,将小的数值,挂到cur上。3.如果list1 或者 list2 还有剩余,那么就将剩余链表直接挂到cur上。1.先创建一个虚拟头节点。原创 2024-04-07 11:15:21 · 131 阅读 · 0 评论 -
142.环形链表2
—当链表存在环的时候,快慢指针第一次相遇之后,手动将快指针的指向调整为头节点,慢指针的位置保持不变,此后快慢指针的步调都调整为1。此后快慢指针再次相遇的时候,即为头节点所在位置。——开始的时候完全没有get到进阶的意思,与环形链表1不同的是,当链表存在环的时候,快慢指针一定会在环中相遇,因此简单题只需要返回True就可。环形链表2需要返回环的头节点。——————想过证明,没证出来。但是画图验证的时候果真如此————原创 2024-04-07 10:42:46 · 193 阅读 · 0 评论 -
141.环形链表
时间复杂度O(n),空间复杂度O(1)。当最后一个指针回指到头节点的时候,slow指针再次回到头节点的时候,slow和fast相遇,所以时间复杂度为O(n)2.每次遍历先判断地址是否在哈希表中,若在则直接返回True;否则,将地址装如哈希表,并且cur指针向后移动。1.cur指针遍历链表,并且创建哈希表,用于记录节点的地址。——————遍历链表,哈希表记录节点——————————————快慢指针遍历——————时间复杂度O(n),空间复杂度O(n)原创 2024-04-07 09:43:07 · 170 阅读 · 0 评论 -
234.回文链表
3.对比原始链表的全部分和后部分是否数值一致,若均一致那么就是回文链表。_____________代码改进_____________2.转数组,若是保持不变就是回文链表。2.利用中间点将后部分链表进行翻转。1.利用快慢指针找到链表的中间点。1.将链表的数值进行记录。原创 2024-04-06 21:02:45 · 137 阅读 · 0 评论 -
160.相交链表
若两链表 有 公共尾部 (即 c>0c > 0c>0 ) :指针 A , B 同时指向「第一个公共节点」node。若两链表 无 公共尾部 (即 c=0c = 0c=0 ) :指针 A , B 同时指向 nullnullnull。头节点 headB 到 node 前,共有 b−c 个节点;头节点 headA 到 node 前,共有 a−c个节点;————看评论区大神的思路————因此返回 A 即可。原创 2024-04-06 18:20:15 · 322 阅读 · 0 评论 -
48.旋转图像
1.矩阵转置:对于第一行第一列元素对应交换。然后row+= 1,col+= 1,表示转置的矩阵缩小一圈,第一行第一列的位置更新 2.矩阵左右交换:若矩阵col为奇数,先找到中间middle(该col不需要交换),对于middle左右的两列相互交换。交换完成,左边列减一,右边列加一,表示不断向外扩展。·解题思路——————将旋转拆分为两步计算:转置和交换。原创 2024-04-06 16:24:32 · 172 阅读 · 0 评论 -
54.螺旋矩阵
3.需要注意的是,第一排遍历完,top += 1;最右边,right -= 1;最下边 bottom -= 1;最左边 left += 1。2.遍历顺序:第一排的从左至右;1.螺旋 == 绕圈。所以就是绕圈遍历矩阵。原创 2024-04-06 15:09:36 · 229 阅读 · 0 评论 -
73.矩阵置零
2.读取flags中的元素,获取要置为0的行列值,然后两个循环将matrix中的对应元素置为0。1.遍历原矩阵,记录0位置的行列值,存入数组flags中,作为标志。1.将原始需要记录行列的数组flags改为两个哈希表row和col。——————改进优化,使用哈希表————————————初步思路,暴力求解——————2.遍历矩阵将0位子的行列分别存入哈希表中。原创 2024-04-03 14:41:56 · 330 阅读 · 0 评论 -
.238.除自身以外数组的乘法
2.稍作优化——先判断是否有0存在,若是在乘积的余下数组中有0直接判断为0 (但是只是最优时间复杂度减少,没什么大作用)1.利用pre数组记录每个元素的前缀积,pre[0]= 1 (图解如下,来源力扣官网)(同样的思路,也可以先用resul记录后缀积,动态字母L记录前缀积,L从前往后移动即可)————————牺牲空间换时间(两个额外数组空间,记录前缀积和后缀积)——————————————时间换空间(for循环暴力求解)—————————————————兼顾时间和空间————————原创 2024-04-03 10:52:22 · 263 阅读 · 0 评论 -
189.轮转 数组
2.使用k将原始数组分为两个部分nums[:n-k] (前部分) 和 nums[n-k:](后部分)3.前部分的子数组的位置改为 nums[k:] 后部分的子数组位置改为 nums[:k]1.其实向后轮转的时候,有部分元素之间的相对位置是不变的,因此可以使用切片的思想进行轮转。(上述代码时间复杂度为O(kn),在leetcode提交的时候37/38算例会超时。2.调用循环,当k>0的时候,不断向后冒泡,并且每次冒出一个元素后k-1。—————冒泡排序的超时算法————————————改进————原创 2024-04-02 22:38:41 · 130 阅读 · 0 评论 -
56.合并区间
2.先判断头两个数组是否可以合并,若是可以合并则直接将合并的结果加入到result数组中;若是不能合并,那么就将两个数组都加入到result数组中。3.进入循环,每次判断获取的数组是否可以和resul最后一个元素合并,若是可以合并,则先弹出数组的末尾元素,然后再添加合并后的结果。4.若是获取的数组不能和result末尾数组合并,那么就直接将获取的数组添加到result中。1.先对数组进行排序。原创 2024-04-02 18:35:18 · 173 阅读 · 0 评论 -
53.最大子数组的和
动态规划:1.主题的思路是递加;2.当传输的前一个递加结果为负数的时候,递加的和结束,从当前开始,及时止损。原创 2024-04-02 16:33:15 · 91 阅读 · 0 评论 -
560.和为k 的子数组
首先是两个for循环暴力求解,然后导致验证超时。转为使用哈希表来记录出现的和的次数。————————暴力求解超时代码————————————哈希表————————原创 2024-04-02 15:44:12 · 111 阅读 · 0 评论 -
438 找到字符串中所有字母异味词
之前的思路都是滑动窗口循环,但是事实证明想多了只需要每次对s字符串中len(p)长度的子字符串进行计数就可以了。只是计数的时候,选择使用哈希表,下标采用编码值(但是其实采用字典应该也可以)只是时间复杂度会高。1.统计第一个子字符串的字母出现次数。若是与count-p相同,则增加0。2.在字符串s中,进行移位,并且统计次数。原创 2024-04-02 12:04:16 · 136 阅读 · 0 评论 -
15.三数之和
首先对数组进行排序(O(n log n)),然后遍历数组(O(n)),并在每次遍历中使用双指针进行线性搜索(O(n))。由于排序的时间复杂度是主导项,因此整体时间复杂度可以认为是O(n log n),但在实际情况下,双指针的遍历是算法的主要瓶颈,因此通常认为是O(n^2)。1.两个循环暴力求解,再找另外一个数字————>超时O(n^3)2.将原有数组分为正负零他,再找,还是超时O(n^3)—————记录一下gpt给的思路————1.排序的好处在于,可以有规律的滑动。3.使用continue去除重复元素。原创 2024-03-30 21:56:46 · 220 阅读 · 0 评论 -
49. 字母异位词分组
1.用join(sorted())函数获取每个单词的字母,作为关键字。2.如果key在字典中存在,那么之间append。4.最后将字典的values作为列表输出即可。3.如果不存在,就新建一个键值对。原创 2024-03-27 12:46:55 · 139 阅读 · 0 评论 -
1.两数之和
【代码】1.两数之和。原创 2024-03-27 11:52:30 · 69 阅读 · 0 评论