自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 19 滑动窗口的最大值

最后再进行优化:超时的原因是当k太大时,我们得堆维护了很多没要必要的值,比如1,3,-1;并且,通过上述逻辑,我们可以知道队首的元素肯定是最大值(因为当我们加入一个值的时候,会将他前面并且比他小的元素都给剔除),因此就不需要创建大根堆去维护值了,使用双向队列或者列表即可。首先我们要创建一个列表,每次加入元素的时候都需要首先将移除窗口的元素从列表中移除,然后从末尾遍历元素,如果队尾有值比他小那么就给踢掉,直到遇到比当前值大的元素;随后就是加入元素,并且获取链表的头节点,就是当前窗口的最大值;

2025-03-29 14:07:42 416

原创 18 和为k的子数组

我们要求的是k,那么我们就可以统计以i目标为结尾的整个字串之和,然后将其存入哈希表中,用当前字串和减去目标值然后去哈下表中找有没有符合的值就可以了;就是说让i遍历数组,每次遍历的时候都将以i位置为结尾的整个字串加入哈希表中。这里需要注意的是,如果正好当前字串的和等于k,也就是说sum-k =0;此时在哈希表中如果没有0值,那么这种情况就被我们丢失了,因此我们首先应该在哈下表中加入(0,1)但是这道题中的值存在0和负数,使用滑动窗口的思想是:窗口内的值小于目标值那么右指针右移动加入窗口;因此我们使用前缀和。

2025-03-29 10:59:05 120

原创 17 找到字符串中所有字母异位词

这道题是定长的滑动窗口,思路就是用哈希表记录目标字符出现的个数,然后再统计当前窗口内字符出现的个数是否一致;

2025-03-28 14:11:49 250

原创 16 滑动窗口-无重复字符的最长字串

这道题求连续区间的最长字串,那么我们可以采用一个for定义i作为右指针,在定义一个左指针,然后用int[]来标记窗口内的字符;每次循环的时候判断当前下标值是否已经存在哈希表中,如果存在那么就让哈希表中的值一直出窗口,直到当前下标值不存在,每次出窗口的时候要记得对总数减一;然后将下标值加入窗口,值加一,每轮统计一下最大值;滑动窗口思想虽然一样但是写法很多,自己能找一种简单不容易出错的方式。滑动窗口可以用集合但是最优的解法是用数组;能用int[]就尽量用。看到这种需要连续的可以想到滑动窗口。

2025-03-28 13:59:52 121

原创 15 LRU缓存

这里面注意的是我们需要一个哨兵节点来辅助,需要让哨兵节点的prev.next以及next.next指向自己,即这里是一个双向循环链表,并且我们每次头插节点的时候都是头插在哨兵节点之后。哈希表是为了随机访问,双向链表是为了能够确定位置。这道题采用双向链表加哈希表;

2025-03-27 13:03:32 424

原创 14 随机链表复制

答题思路是,首先将所有节点都复制一遍,然后原先节点作为key,复制的节点作为value,那么当我们复制一遍过后,在进行一次遍历,就是处理next和random,如何处理呢,就是通过map.get(cur.next)就可以了。如果是普通的链表,那么我们只需要记录当前节点和下一个节点,然后new完后直接连起来即可,但是现在多出一个random,因为我们不知道这个random是否已经被创建出,并且其位置也很难找,因此我们用一个哈希表来标记。这道题是复制节点,深拷贝。

2025-03-26 18:17:16 133

原创 12 排序链表

设置两指针 left, right 分别指向两链表头部,比较两指针处节点值大小,由小到大加入合并链表头部,指针交替前进,直至添加完两个链表。递归分割时,输入当前链表左端点 head 和中心节点 slow 的下一个节点 tmp(因为链表是从 slow 切断的)。递归额外空间:递归调用函数将带来 O(logn) 的空间复杂度,因此若希望达到 O(1) 空间复杂度,则不能使用递归。我们使用 fast,slow 快慢双指针法,奇数个节点找到中点,偶数个节点找到中心左边的节点。找到中点 slow 后,执行。

2025-03-26 16:07:04 664

原创 插曲13 归并排序

归并排序就是将一个数组中数据不断二分,直到分到只有一个为止(左端点是left,右端点是right,那么当left >= right的时候就不需要在分了),此时开始合并,用两个指针分别遍历两个数组,哪个值小就放入新数组中,然后把两个数组的值都遍历完并放入新数组中后,在通过新数组将排序后的值放入原数组中即可。这里有个非常好理解的思路,就是可以把归并排序当作二叉树的后序遍历,因为要达到当前节点的合并条件,那我们首先需要将其左右子树都排序完,那么最后才会对当前节点进行排序。

2025-03-26 15:38:07 384

原创 11 K个一组反转链表

所有的链表题都能拿数组来做,而且很轻松,为了避免出错,用int[]更好,因为List的方法不熟悉容易出错;思路就是将链表中每个节点的值放入链表中,最后将每组的节点进行倒序(前后互换位置即可),最后Nwe一下连接到一起即可。根据栈先进后出的原理,当我们将其放入再取出后自然就是逆序的,所以我们现在做的就是按将每组节点放入再取出,然后连接即可。list中的方法:查看下标元素list.get(i),将下标元素设置成val:list.set(j,val);同时我们需要去记录每组链表的尾节点便于下一组链表的连接。

2025-03-25 13:10:57 309

原创 10 两两交换链表中的节点

说一下思路:就是我们定义四个指针,第一个指针指向我们创建的新节点(好移动),其他指针分别指向head,head.next,head.next.next;然后模拟指针交换的过程即可。当前我们的任务是,将节点两两逆序并返回头节点,那么我们就可以规定每个递归中的任务就是,将两个节点逆序后返回逆序后的头节点。需要递归的话我们就需要将其中的重复问题剥离出来。就是我们只需要模拟一下交换过程即可。

2025-03-24 14:09:09 151

原创 9 删除链表中的倒数第n个节点

就是我们要删除倒数第n个节点,那么我们用一个快指针走n格子,然后用慢指针和快指针一起走,那么当快指针指向为null的时候,此时慢指针指向的节点就是需要被删除的节点;要注意,因为此时慢指针是我们要删除的节点,我们无法直到删除节点的前一个节点,因此我们的慢指针不能从head出发,要定义一个节点去指向head;另外还需要注意的一点是,我们最后结果不能返回head,因为head就有可能是被删除的值,我们上述定义了一个节点,因此我们需要返回的是这个节点的.next。

2025-03-22 17:44:49 172

原创 8 两数相加

我们直接将两个头节点的值取出进行相加即可,相加完之后取余(就是只拿个位数的值),然后将其生成一个节点,穿起来即可,同时要记录其十位数字与下一次的链表头节点进行相加,这样一直迭代下去就可以了。

2025-03-22 17:21:00 135

原创 7 合并两个有序列表

就是我们将每个子问题抽离出来,问题就是每次传入两个链表的头节点进行比大小,选出值较小的节点,值较小的那个节点。之前做过合并k个有序列表,两个方法是一样的。

2025-03-22 16:53:32 241

原创 5 环形链表2

如果有的话,那么找到二者第一次相遇的位置,然后将一个指针重新指向头节点,另一个指针指向相遇的节点;然后两个指针以相同的速度前进,之后相遇的那个节点就是入口。这个题是一个纯数学问题,感兴趣的可以去b站看代码随想录的题解。首先利用快慢指针判断是否有环,没有的话返回Null。这里简单说一下代码思路。

2025-03-22 15:43:29 186

原创 环形链表1

我们可以用快慢双指针,一个指针每次走一格,一个走两格,如果是循环链表,那么快指针总会有一次追上慢指针并重合;否则当faset.next==null||fast.next.next==null那么就返回false;注意两个指针不要一开始从头节点出发,不然一开始就判定为true了,同时注意边界情况,就是指针下一次引用为null。这是个数学问题,演示一下就行。

2025-03-22 14:28:10 177

原创 4 回文链表

判断的时候要注意分情况,因为链表长度可能为奇数也可能为偶数,如果为奇数那么只需要head!= reHead跳出循环的时候还需要判断head.val是否等于reHead.val。两种方式:利用双指针,一个每次走1格,一个每次走两格;另一种遍历出链表长度之后,再遍历一遍找到中间节点,然后把中间节点后的链表倒序,就是上一道题的链表反转,最后从节点头和节点尾进行依次判断。就是将链表中的值依次放入数组中,在数组中判断回文应该非常简单了吧,只需要判断左下标的位置是否大于右下标即可。

2025-03-22 14:12:57 191

原创 3 反转链表

递归的思路就是找出同一件事情,通过题目可知,我们现在的目的就是将下一个链表的引用指向前一个,并且返回头节点,因此,我们就可以先通过递归递归到尾节点,然后返回尾节点,尾节点就是反转后的头节点,所以要被当作返回值返回;同时要改变当前节点下一个节点的引用,然后将当前节点的引用置为null。另一种代码的实现思路,就是说我们想把返回的节点当作当前节点的下一个节点,最后返回头节点,那这样就需要用一个成员变量对尾节点进行标记,用一个方法,只负责排序,最后在原方法中返回排完序的尾节点即可。

2025-03-22 13:37:13 214

原创 2 相交链表

比较两个链表的长度,然后让较短的链表走二者长度之差,此时两个链表就一样长了,开始用双指针遍历,如果有相等返回,没有返回null;一直循环遍历两个链表,如果二者有重复节点那么肯定会相遇,没有也会在某一时刻返回空(看看即可)为了减少冗余代码,我们设置一个minCur和maxCur分别代表短长链表,让长链表走即可。遍历一个链表,放到hash中,在遍历另一个链表,看哈希表中是否存在。其中应该交替循环,不然时间复杂度会很大(没搞清原理)

2025-03-22 13:00:35 121

原创 1 合并k个升序链表

注意方法:queue.offer()添加元素 queue.poll()取出堆顶元素 ,小根堆(a,b) -> a.val-b.val;最后注意要判断当前节点不为空,才能放入小根堆当中。直接将所有的节点值放入klist当中,然后再用Collection.sort进行排序,排完序之后把每个值new成一个节点,这样串起来就好了。先把头节点放到小根堆中,然后取出堆的头结点,如果下一个节点不为空,那么再放到小根堆中,直到堆为空;(不知道为什么把全部节点放进去排序会出现循环链表,搞不懂)

2025-03-22 10:56:41 158

原创 MySQL中重复多条语句问题

这行代码将唯一记录插入到临时表中,基于 column1 和 column2 进行去重,只保留 id 最小的记录。标记要删除的重复记录:我们使用自连接 INNER JOIN 来找到重复的记录,并且使用 WHERE t1.id > t2.id 来确保只删除 id 较大的记录,从而保留 id 最小的记录。将临时表中的记录插入回原始表。为了避免改变原来的数据 ID,我们可以使用一个不同的方法,通过使用自连接来标记重复的数据并删除多余的记录。这样,你就成功地删除了原始表中的重复记录,只保留了一条唯一记录。

2025-03-16 00:02:26 427

原创 网关的详细介绍

spring.cloud.gateway.metrics.enabled: metrics表示指标相关的配置项,enabled 是一个布尔类型的配置参数,当设置为 true 时,意味着开启Spring Cloud Gateway的指标收集功能.开启指标收集功能后,Spring Cloud Gateway会收集一系列与网关运行相关的指标数据.这些指标数据能够帮助开发者和运维人员更好地了解网关的运行状态,性能表现以及流量情况等.

2025-03-13 23:59:03 544

原创 mysql简介和安装

数据库就是用于存储和管理数据的仓库,英文:DataBase(简称:DB),而在数据库中的数据也是有组织的进行存储!关系型数据库指的是多张相互连接的二维表组成的数据库,所谓二维表指的就是由行和列组成的表,如下图(就类似于Excel表格数据,有表头、有列、有行, 还可以通过一列关联另外一个表格中的某一列数据)。还有MySQL、Oracle、DB2、SQLServer这些都属于关系型数据库,里面都是基于二维表存储数据的。

2024-11-21 23:15:10 935

原创 redis的缓存问题

就是因为MySQL这种关系型数据库效率比较低,所以可以承担的并发量比较有限,一旦请求多了,数据库的压力就会很大,甚至发生宕机.如果想要解决MySQL并发量的问题,我们有两种解决的策略,一种是开源,就是引入更多的机器,构成数据库集群,另一种就是节流,即引入缓存,这就是典型的方案,把一些频繁读取的热点数据,保存到缓存上,后续在查询数据的时候,如果缓存中已经存在了,就可以不再访问MySQL了.Redis也就相当于一个护盾一样,把MySQL给罩住了.

2024-11-20 17:31:59 987

原创 redis哨兵选举

port,代表的是端口映射,我们知道docker可以理解为一个轻量级的虚拟机,在这个容器中,每个进程也都有属于自己的端口号,而docker本身又存在自己的宿主机,比如6380:6379,6380代表的是在宿主机上的进程端口号,6379代表的是在docker容器中的端口号,这样我们就可以在宿主机上通过6380端口号访问到docker容器中的6379端口号进程,这里的端口映射,有些像我们之前在本地配置访问redis的隧道.

2024-11-20 17:30:25 781

原创 redis主从复制

主从主从,顾名思义就是有的服务式"主"结点.有的是"从"结点.比如我们有三台物理服务器(称为三个节点),此时就可以把其中一个节点,作为"主节点",而另外两个作为"从节点".这时候,从结点就必须听主节点的,从结点的数据要跟随主节点变化,从结点的数据需要和主节点保持一致.也就是主节点原有的数据,在与从结点建立连接之后,就需要把主节点上面的数据复制到从结点上,后续主结点这边对于数据有任何修改,都会把这样的修改也同步给从结点上.说的再简单一点,从结点就是主节点的一个副本.在第5步的时候,验证的步骤具体是什么呢?

2024-11-20 17:28:17 765

原创 redis持久化

随着AOF文件体积的持续增长,体积会越来越大,这就会影响到Redis的下次启动的启动时间.Redis在启动的时候,需要读取AOF文件的内容,我们知道,在AOF中记录的是我们操作Redis的中间过程.实际上,Redis在重新启动的时候,关注的是最终的结果.这时候,AOF就可以把一些冗余的数据进行优化,剔除其中的冗余操作,并且合并一些操作,达到给AOF瘦身的效果,这就是AOF的重写机制.RDB是⼀个紧凑压缩的⼆进制文件,代表Redis在某个时间点上的数据快照。非常适用于备份,全量复制等场景。

2024-11-20 17:25:49 520

原创 使用spring操作redis

就像我们去吃烧烤,如果有一部分烧烤还没有上来,我们就需要退款,这时候老板就到后厨看了一眼,说已经烤上了,退不了了,再比如我们在遍历Redis服务器中的key的时候,遍历了一半,不想遍历了,但是这时候又取消不了,如果强行退出,这时候服务器就会保存状态,这时候就会对服务造成一定的影响,这时候就相当于服务器保存了客户端的状态.再比如我们去超市买东西,如果我们在结账的时候,发现钱没有带够,后面的东西不想要了,这时候可以不扫后面的商品.这时就像Redis中的渐进式遍历,没有保存之前遍历的状态,可以随时停止.

2024-11-13 00:47:33 1107

原创 Redis的String相关操作

这里我们需要注意的是.Redis中存储string的方法和java中,MySQL中的存储方式并不一样.Redis中存储字符串的时候,会直接存储字符串的二进制数据,不会对二进制数据做出任何的编码转换,存入的是什么,取出的还是什么,但是java和MySQL不一样,java中存储字符串的时候会涉及到编码方式的问题,MySQL中,字段不可以插入中文,这是因为MySQL的默认编码方式是拉丁文,与汉字不兼容.将key对应的string表示的浮点数加上对应的值。如果对应的值是负数,则视为减去对应的值。

2024-11-11 23:17:05 587

原创 redis基本操作

开发环境: 在项目未上线之前,我们需要对一款软件进行开发,我们在开发的时候所在的操作系统的环境叫做开发环境.有些情况下,我们会使用本机的环境进行开发,也就是办公环境和开发环境是一样的,但是很多时候,公司也有专门的开发环境的服务器.有些情况下,一些软件的业务逻辑比较复杂,这时候本机环境是带动不起来的,就需要性能更高的服务器来带动.redis中的单线程模型指的就是,redis在处理命令的时候,都只使用一个线程来处理,说redis只有单线程,其实也有使用多线程的地方,在网络io中使用的就是多路复用的情况.

2024-11-10 23:51:24 791

原创 分治-快排思想题集1

当右边区域的元素数量小于k时,那说明第k大的元素不在该区域内,此时如果中间区域加上最大区域的元素个数大于k,那么说明第k大的值在中间区域,直接返回中间区域的任意一个值即可。当最小区域的数大于k的时候,那我们继续对最小区域的数进行排序,直到中间区域加上最小区域的数大于等于k,那我们就可以直接返回(因为题目中不要求有序,所以符合条件就直接返回),如果左区域和中间区域的元素个数小于k,那我们就只对右区域的(k- a-b,a,b分别为左,中区域的元素个数)个数进行排序即可。大家有兴趣可以看一下,

2024-04-15 18:48:48 1026

原创 滑动窗口题解2

来记录right遍历的时候存入的有效字符。什么是有效字符,比如p的字符个数为2,那么我们用滑动窗口遍历字符串s的时候,如果这个字符在mapP中,并且mapS的该字符个数小于等于mapP时我们就count++,如果遇到的字符不在mapP中count就不++。当我们再2开始遍历的时候可以发现和从0开始遍历是相同的,因此到2的时候就无需再遍历一次了。这道题的思考点在于如何直到是否有两种以上的不同数字,我们可以用map,如果map.size()没有超过2,那么继续往里面加,如果超过2那么就左移left。

2024-04-15 18:48:38 753 1

原创 二分法题集1

二分法题记归纳与总结

2024-04-06 20:20:53 1315 2

原创 二分法题集2

接下来我们要找到这道题的二分性。我们可以发现如果选取数组第一个值为参考时,则最小值到该数区域内均大于该数,最小值到数组末尾均小于该数,那么我们就可以转换为找出第一个小于数组0小标值的元素。这道题中题目给了我们思路,目标值的左边均是递增,目标值的右边均是递减,那么我们就可以根据递增递减作为二分依据,然后就可以将题目转换为找出数组中最后一个递增的下标(同理我们也可以转换为找出第一个递减的下标)。1 数组中左右边界值都是无穷小,因此我们可以理解为,递增数组的最后一个值就是峰值,递减数组的第一个值就是峰值;

2024-04-06 18:46:48 450 1

原创 泛型的进阶

本文介绍了泛型的进阶----通配符以及泛型基础知识的链接

2024-03-27 21:24:32 327

原创 字符串常量池

当hello第一次出现的时候,系统先会在常量池中是否存有hello,如果没有那么就在常量池中存储hello,当第二次使用hello的时候,这时在常量池中可以找到hello,hello就不需要在存储了。再来看这两张图,我们要注意,s1中会创建新的对象,这个对象指向的是一个字符数组,并不会存储在常量池中,只有s2的“abc”会存储在常量池里。s1和s2并没有创建新的String对象,s1,和s2的地址相同,都指向的是常量池中的String对象。s3----->创建的String对象------>常量池字符。

2024-03-27 21:22:14 392

原创 数组划分,双指针

代码中,要先让desc == -1,防止数组第一个元素是0,如果arr[cur]不为0,那就让desc++,并且,我们提到,数组左边到desc是非0区,所以如果遍历到的不是0,那么就要放到非0区,而放到非0区的做法就是交换desc后一位元素和当前元素的位置。因此,desc指向的是非零元素的最后一个元素。这个时候分析案例可知,有个特殊情况,当快指针在倒数第二个位置时,慢指针为0的话,此时快指针会走两步,那么快指针就会越界,这种情况下,当我们在复写的时候,末位置的0不需要复写,因为我们处理完这种特殊情况即可。

2024-03-24 23:02:40 703 2

原创 链表精选题集

上面说过,如果改变某一个节点的指向时,那么这个节点之后的可能就会丢失。这道题就按常规思路来解题,我们要想判断两个链表是否相交,那我们就要看他们是否有相同的节点,如果有的话,那么这个节点及其以后的都一样,只是这个节点前的部分不一样,假设有个指针指向节点A,另一个指针指向节点B,如果两个链表相同节点前部分长度相同,那么只需要A,B走相同步数就可以走到相同节点,但是如果长度不一样差了n步,那么我们就可以先让长的链表先走n步,之后两个链表再一起走,如果A==B那么说明两个链表相交,否则不相交。

2023-12-30 20:53:23 993 4

原创 链表的详细介绍

链表中每个元素称为节点,每个节点由两部分组成(单向链表):数值和next域,next域存储下一个节点的地址,例如下图,可知链表在内存上不一定连续链表又节点和头节点组成,每个节点又由数值和next域组成,那么我们可以把节点定义做内部类‘定义成静态内部类比较方便应用,再者为什么next的类型时ListNode呢,因为每个节点的nxet域是指向下一个节点的,因此头节点和next的类型均为ListNode;同时因为每个链表的头结点只有一个,所以应该定义在LIstNode之外。链表的集合类;

2023-12-26 18:16:48 929 6

原创 ArrayList和顺序表

ArrayList是Collection的子类,所以arrayList满足第一个条件,arrayList中的元素均是String类型的,所以当传入参数的元素类型是String或者其子类的时候就可以编译成功;ArrayList就类似数组,但为什么还有创建这个类,是因为当我们需要知道并运用这个数组的有效存储元素时,数组是无法满足的(比如数组整体有五个元素的大小,但实际上只存储了三个元素),而且ArrayList当中有很多方法可以使用;但与字符串不同的是,字符串的改变是产生新的对象,常见的有:顺序表,链表。

2023-11-28 00:52:15 1153 18

原创 泛型的详细介绍

第三处,泛型就可以作为一个类型,其类型的决定取决于实例化泛型类时所给的类型,例如MyMap<>中给的是String类型,那么T就代表String类型,给setArray传值的时候也必须传String类型,在实例化MyMap的时候,也就是第五处的<>可以不写类型。数组是一种单独的数据类型,int[],double[],Object[]都是各自独立的数据类型,不同于String,Object数组不存在继承关系,因此无法将int[]类型的数组传给Object[]类型的数组;由基础类型转为包装类型叫做装箱;

2023-11-26 14:12:47 1000 8

空空如也

空空如也

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

TA关注的人

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