自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 6. Z 字形变换

我们肯定想到用数组来存放一下最后遍历数组组合,因为str

2025-01-16 12:13:34 270

原创 151. 反转字符串中的单词

看到这个我们首先就是要去除前导空格和尾随空格,中间连续空格变为单个空格,这些做完后我们再去进行翻转,也就是用两个指针(一个指头一个指尾),交换指针内容然后往中间靠近。要求:反转后的字符串中不能存在前导空格和尾随空格,如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。

2025-01-16 12:06:00 106

原创 14. 最长公共前缀

纯遍历,我们可以用多个指针指向每个str的开始然后遍历直到不满足。

2025-01-16 12:02:44 102

原创 58. 最后一个单词的长度

我们首先想到要去除前导空格和后导空格,然后找到最后一个空格(一定在最后一个单词前)

2025-01-16 12:01:10 66

原创 http和https有哪些不同

它利用椭圆曲线上的离散对数问题,生成临时的公钥和私钥对,确保每次通信的密钥都是独立的,提供前向安全性。3.客户端密钥交换 + 使用加密 + 客户端完成:客户端密钥交换:客户端在验证完服务器的证书后会发送密钥给服务端并且这时还会生成一个新的随机数,然后发送“开始加密”和“客户端结束”消息给服务端。我们可能的第一想法就是http是不安全的https是安全的,但是可能不怎么了解为什么,我们现在可以从底层出发了解一下为什么https是安全的。1.数据传输的安全性:http非加密,https加密。

2025-01-13 23:41:39 3119

原创 tcp的三次握手和四次挥手(超详细+图解)

我们这样来看好像是行的,就是要改变一下策略,原先可能服务端收到了客户端的断开连接请求后可以直接先返回一个ack然后做好断开连接的准备(把要传的数据传完),准备好在发FIN;其实就像一个计时器,服务器收到连接请求后会把连接放入半连接队列然后发送ack和syn,只有客户端在规定时间内返回正确的ack,连接才会被放入全连接队列,否则服务器就会重发ack和syn直到到达最大重传次数(默认值为5)2.第二次握手:服务器接受到客户端发送的syn(x),然后发送ack(x+1)和syn(y)给客户端。

2025-01-13 23:38:46 1256

原创 12. 整数转罗马数字

2.如果该值以 4 或 9 开头,使用 减法形式,表示从以下符号中减去一个符号,例如 4 是 5 (V) 减 1 (I): IV ,9 是 10 (X) 减 1 (I):IX。仅使用以下减法形式:4 (IV),9 (IX),40 (XL),90 (XC),400 (CD) 和 900 (CM)。你不能多次附加 5 (V),50 (L) 或 500 (D)。1.如果该值不是以 4 或 9 开头,请选择可以从输入中减去的最大值的符号,将该符号附加到结果,减去其值,然后将其余部分转换为罗马数字。

2025-01-12 22:51:55 215

原创 13. 罗马数字转整数

比如:IV=5-1=4,IX=10-1=9,XL=50-10=40, XC=100-10=90, CD=500-100=400, CM=1000-100=900,那我们这要将这些升序数找出来就行,这就可以用到我们的单调栈来解决。我们显然可以总结出一这么一个规律:罗马数字如果大的数放在小的数右边就是代表这个数是减操作(最又侧的大数减左侧的小的数之和)

2025-01-12 22:49:45 245

原创 135. 分发糖果

对于两个相邻的孩子我们给得分高的更多的糖,我们首先从左到右看如果右边的孩子分更高我们就让右边孩子的糖比左边的孩子多一颗,但是这样有一个问题就是如果左边孩子的分更高怎么办,其实按照上面的做法我们从右到左做一遍就能处理这种情况,然后我们将上面两中综合一下取个最大值(为什么是最大值呢,因为要求比周围比他分少的孩子糖更多)

2025-01-12 22:46:15 341

原创 134. 加油站

看这道题我们先考虑刚开始能不能开到下一个加油站,也就是gas[i] >= cost[i],之后我们就可以往后尝试了,sum记录车有多少油因为题目说答案唯一所以我们找到后就退出,没找到就重复上面。如果i不能到j + 1的话那i到j间的任意一点也到不了,因为有前面的油的余量,所以我们可以直接从j+1开始尝试。所以我们从发现i到不了j后就可以从j+1继续,这样我们只要遍历一次加油站就行,花费O(n)

2025-01-05 22:32:23 205

原创 380. O(1) 时间插入、删除和获取随机元素

一看题解好家伙用了hashmap(这真是蚌埠住了),如果不让我们自己实现hash的话还是比较容易的所以最后也就是ArrayList + HashMap,arraylist存数据,hashmap存下标。但是后面往深想又发现一些问题,因为如果用ArrayList的话想要实现O(1)插入就只能插在末尾,但是这样查找就麻烦了,肯定要有别的变量存插入的下标。如果用定长数组的话你就会发现冲突概率太高了,比如16的初始空间 1,17,33等全都冲突了,所以这题自己实现起来还是太麻烦了不像中等题,

2025-01-05 21:52:03 207

原创 274. H 指数

问题分析:看到这题后我的第一想法就是直接排序呗(升序),因为论文的顺序又没有影响我们只要从高到低遍历引用数组,然后比较citations[i]与len-i(大于这篇论文引用数的论文数),取两者间小的,最终ans则是所有结果中大的。最后时间复杂度就是O(nlogn),(用了Arrays的sort,底层应该是快排)

2025-01-05 00:13:22 177

原创 122. 买卖股票的最佳时机 II

和买卖股票的最佳时机I这题相比,区别就是可以买多只股票虽然同时只能持有一支,但是我们还是可以运用贪心的思想只要盈利我就卖出,因为你看 2 4 6 我在2买入4卖出赚2,4买6卖赚2,和2买6卖是一样的,如果 2 6 4,我在6卖出不影响,因为如果后续有大于6的我还能卖,如果没有大于6的那我6的时候卖就是最优的。

2025-01-05 00:10:23 343

原创 MySQL的最左匹配原则是什么

这条语句因为我们跳过的f2所以无法走索引得走全表查询,但是如果我非要走索引呢(索引的效率多高啊),所以mysql的优化器就想怎么才能走索引呢,我们是因为跳过f2才导致索引失效的,那么我补上f2不就行了吗,因此优化器会隐式的帮我们补上,例如:.....where f2 = 1 and f3 =?大部分导致索引失效的情景都会导致最左匹配失效,有个要注意的就是如果对靠左的索引使用了不含等值的范围查询(>,<,like(%xx))会导致查询结果无序,后续索引自然无法使用。对于以下表F:f1,f2,f3;

2025-01-03 22:18:31 778

原创 跳跃表(跳表)是什么

正常链表只能一个一个往下走但是如果我直到我的目标位置就在链表的中部但是我还得一步一步走过去很浪费时间,所以跳表就是在正常链表的基础上添加了多步跳跃的指针。跳表(Skip List)是一种概率型的数据结构,它是基于链表的,通过创建多个层次的链表来加快搜索速度。每个节点不仅有指向下一节点的指针,还可能有指向更高层次节点的指针,从而实现快速跳跃。跳表的时间复杂度为 O(log n) 级别,适用于插入、删除和查找操作。

2025-01-03 22:15:55 1391

原创 26. 删除有序数组中的重复项 and 80. 删除有序数组中的重复项 II

还是两个指针index1和index2,我们先让index2走如果指向的数不等于index1的数那就说明这个数已经没了我们把index1指向的数放到nums中再让index1跳到index2,如此重复。和前一题不同就是保留两个,所以我们要么添加一个(index2 - index1 < 2),要么添加两个呗(index2 - index1 >= 2),至于最后一个数的判断也是一样的。给我们的nums数组是非严格递增的所以后面出现的数至少大于等于前面的数。

2025-01-01 19:20:47 218

原创 27. 移除元素

因为评测机会帮我们排序所以我们可以不排序,还是双指针一个指针指向下个数放哪,一个指针指向现在遍历到哪,只要O(n)就行。

2025-01-01 19:17:26 216

原创 88. 合并两个有序数组

这题不难很常见的双指针比较,注意不要越界就行,n等于0的时候特判一下。如果要时间O(n+m)的话我暂时只能想到复制一个新数组出来。

2025-01-01 19:15:41 181

原创 121. 买卖股票的最佳时机

但是我们怎么计算处maxValue数组呢,暴力肯定不行,所以我们可以通过map来记录我们还未遍历过的数的个数情况,我们每遍历过一个数我们就将他的个数-1,当减成0后我们就从map中移除他,如果我们我们上一次求出的maxV还在map中那么这个数肯定就是maxV,否则我们再去重新求maxV,这样可以极大降低时间复杂度。然后遍历找到最大的值。虽然已经提示我们使用贪心算法了,但是我最开始的时候却不知道怎么使用,因为如果我找最小的天购入但是不一定卖的出去(还是有点太全局思维了后来看来题解才明白)。

2024-12-28 19:28:39 453

原创 35. 搜索插入位置

其实与java中Arrays中的binarySearch()方法非常类似,我们肯定时用二分法来解决,但是如果退出循环后l指针指向的值小于target就意味着target的实际存放位置是l+1,如果大于target那么target就应该替代l位置的数,最后我们还要考虑下标是否会越界,如果l越界说明target的值一定是比nums中的数都大,所以也是直接放到l的位置就行。

2024-12-28 19:10:43 247

原创 什么是JSR-133的happens-before规则

线程中的每个操作都先行发生于对此线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值检测到线程已经终止执行。:如果线程A执行操作ThreadB.start()(启动线程B),那么A线程的ThreadB.start()操作先行发生于线程B中的任意操作。:对象的interrupt()方法的调用先行发生于被中断线程的代码监测中断事件的发生。:在一个线程内,按照控制流顺序,书写在前面的操作先行发生于书写在后面的操作。

2024-12-18 11:38:21 275

原创 synchronized与volatile关键字的区别

时,编译器和运行时都会注意到这个变量可能会被多个线程同时访问,因此每次读取变量时都会从主内存中读取,而不是从线程的本地缓存中读取。它通过锁定对象来确保同一时间只有一个线程可以执行同步代码块,从而避免了并发问题。确实可以解决可见性问题。当一个线程修改了某个变量后,其他线程可以立即看到这个修改。它只能保证对变量的读写操作是原子的,但不能保证复合操作(如。会确保对共享变量的修改对其他线程是可见的。主要解决可见性问题,但不保证原子性。可以解决可见性和原子性问题。或其他同步机制来保证。

2024-12-18 11:37:19 400

原创 SpringBoot原理(起步依赖和自动装配)

这个类中重写了selectImports方法将" META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports "这个文件中记录的全类名加载到string[]中然后由springboot进行自动装配。",这个方法返回一个string数组,这个数组中如果添加了对象的全类名,那么这个对象就会被springboot自动装配。的一个子类,在ImportSelector类中有一个十分重要的方法"

2024-12-18 11:34:38 402

原创 JVM的垃圾回收机制

(默认的大小分配是8:1:1),其中,Survivor区间中,某一时刻只有其中一个是被使用的,另外一个留做垃圾收集时复制对象用,在Eden区间变满的时候, GC就会将存活的对象移到空闲的Survivor区间中,根据JVM的策略,在经过几次垃圾收集后,任然存活的对象将被移动到老年代。这时因为并发标记与重新标记阶段都是从灰色对象开始遍历,而C没有与任何一个灰色对象连接,所以C不会被标记,会被当成垃圾回收,这时候问题就很严重了,应为A还引用了C呢,在业务层面需要C对象,这必然会导致严重的事故。

2024-12-18 11:32:28 1777

原创 socket服务器多线程优化

语句获取到连接,但是还需要将这个连接交给worker线程来处理读写请求,这就要求我们一定存在worker线程并且正在工作,但是工作状态的worker线程在没有任务进来的情况下会被多路选择器(selector)阻塞在select方法处,而我们又需要将连接sc注册到worker的selector上让它去监听这个连接上的事件,由于selector被阻塞我们无法完成注册,这就尬住了。但是引入多线程后线程间的执行顺利我们需要控制,比如当boss线程接收到一个请求后执行。

2024-12-17 11:45:12 648

原创 bio与nio与多路复用(补充)

nio发送请求后不会进入阻塞,但是因为请求一版都是配合while(true)实现,所以nio会不断在用户层和系统层间切换查询结果,知道系统层将结果传给用户层,这样虽然不像bio一样一旦被阻塞只能等待当前事件完成才能执行别的事件,但频繁的在两个层级间切换开销大,性能不高。多路复用模式采用两者结合,在没有事件触发时会阻塞等待,当有事件触发后则会执行事件,这样不仅避免了bio在等待数据时的浪费效率,又避免了nio在等待事件时的不断切换带来的性能开销。因为java不具备读写的能力需要调用内核态的读写功能。

2024-12-17 11:42:47 315

原创 敏感词过滤

基于DFA(Deterministic Finite Automaton,确定性有限自动机)算法的敏感词过滤是一种高效的方法。DFA算法通过构建一个状态机来匹配敏感词,其核心思想是将每个敏感词转换成一个状态机,然后通过遍历文本来检测敏感词。虽然DFA算法在很多场景下表现良好,但它并不是唯一的解决方案,也不一定是所有情况下最高效的算法,还有AC自动机和字典树(前缀树)等算法。适应快速定位查找的数据结构我们很容易想到HashMap,但我们的理想结构是类似底层HashMap(hash+树的结构)

2024-12-17 11:25:09 300

原创 二叉搜索树/平衡二叉搜索树

由于这些性质,二叉搜索树可以高效地进行查找、插入和删除操作。:平均情况下是O(log n),最坏情况下是O(n)(当树退化成链表时)。:平均情况下是O(log n),最坏情况下是O(n)。:平均情况下是O(log n),最坏情况下是O(n)。二叉搜索树的这些操作通常通过递归或迭代的方式实现。递归实现更为直观,而迭代实现可以避免递归带来的栈溢出问题。

2024-12-11 11:01:42 959

原创 关键路径求解

在带权有向图中,以顶点表示事件,以有向边表示活动,以边上的权值表示完成该活动的开销(如完成活动需要的时间)。关键路径(Critical Path)是项目管理中的一个概念,它指的是项目中最长的任务序列,决定了完成项目所需的最短时间。关键路径上的任务称为关键任务,它们对项目的完成时间有直接影响。事件的最早发生时间ve,事件最迟发生时间vl,活动的最早发生时间ae,活动的最迟发生时间al,活动冗余时间d=al-ae。(1)在AOE网中仅有一个入度为0的顶点,称为开始顶点(源点),它表示整个工程的开始;

2024-12-11 10:47:09 340

原创 最小生成树

最小生成树(Minimum Spanning Tree,简称MST)是一个图论中的术语,它指的是一个图的边的子集,这个子集构成一个树,并且包含原图中的,同时这个树的边的总权重(即所有边的权重之和)是所有可能的生成树中最小的。

2024-12-11 10:44:38 1020

原创 算法——差分

差分可以看作是前缀和的逆运算,前缀和可以帮我们快速得到某个区间的和,而差分就是我们将原数组看作是一个前缀和数组(q[])我们去构造一个差分数组(c[])

2024-12-10 16:36:21 823

原创 算法——前缀和

如果我们想要得到数组中一段区间的和最朴素的想法肯定是我们从区间的开始下标遍历到结束下标并累加,但是这显然存在一个问题,时间开销是O(n)的级别,并且有着大量的重复计算,求[n, m]的和后继续求[n…m…p]区间和,但是我们还是需要从n开始遍历而不是利用我们之前算过的结果,前缀和就可以帮我们减少重复计算。

2024-12-10 16:28:27 283

原创 迪杰特斯拉算法(Dijkstra‘s)

迪杰斯特拉算法(Dijkstra's algorithm)是由荷兰计算机科学家艾兹格·迪科斯彻(Edsger W. Dijkstra)在1956年提出的,用于在加权图中找到单个源点到所有其他顶点的最短路径的算法。这个算法广泛应用于网络路由、地图导航等领域。

2024-11-21 22:21:57 1054

原创 279. 完全平方数

从题目描述来看是不是有点像完全背包问题,每个平方数就是物品我们能无限装入,但是这次是要我们求最少装入的物品数且恰好将背包装满。我看题解还有通过数学推导得到规律的解法感兴趣的可以去看看。

2024-11-21 22:17:14 189

原创 背包问题(动态规划)

背包问题是一种组合优化的问题,它有多种变体,但最常见的两种是0/1背包问题和完全背包问题。

2024-11-20 23:00:03 982

原创 并查集讲解

也是利用树形结构,每个员工(节点)都会记录自己的直接上级(父节点),如果一个节点没有上级就代表它是boss(一个公司只有一个boss),这个boss直接或间接管辖的所有员工,这个boss管辖下的员工自然是一伙的。现在我们来考虑这么一件事,如果B公司因为经营不善破产了,B公司的老板一看A公司发展的挺好的就先投靠A公司,A公司的老板想了想觉得划得来就同意了,但是他也想要B公司有经验的员工又不想打乱B公司的原本的管理架构,所以他想了个好办法只让B公司老板认他当上级其余不变,这就完美解决了问题。

2024-11-20 22:05:10 442

原创 24. 两两交换链表中的节点

1.对于a->b->c,我们要交换a、b就要知道a、b、c三个节点,因为我们需要将a的next指向c,将b的next指向a,由于b->c这条路断了而c的next指向d,所以我们还需要保存c才能继续往下走,我们将b看作curr它每次前进两步,a看作prev,c看作next,每次使curr.next = prev, prev.next = next,然后令prev = next, curr = next.next,next = curr.next当prev或curr有一个为空就退出.

2024-11-19 19:56:59 399

原创 19. 删除链表的倒数第 N 个结点

删除一个节点后我们要保证后续节点不断开所以需要知道当前节点的前后节点,对于倒数第n个节点可以使用双指针,一个指针先走n步,然后两个指针一起走,当先走的指针到达末尾时,后走的指针正好到达倒数第n个节点的前一个节点。3.要删除的节点是中间节点:将当前节点的前一个节点指向后一节点。2.要删除的节点是尾节点:将当前节点的前一个节点指向null。1.要删除的节点是头节点:返回当前节点的next。

2024-11-19 19:54:32 193

原创 2. 两数相加

我们很容易想到用一个变量surpass记录进位,然后从后往前遍历,但是这样需要处理很多边界情况,所以我们再指定尾节点tail,然后从前往后遍历,这样只需要处理一个边界情况,就是某一条链表遍历完了但另一条还没有,我们让tail等于遍历完的链表的尾部然后将剩余的节点接上去就行.

2024-11-19 19:52:40 218

原创 146. LRU 缓存

将某个节点移动到链表头部或者将链表尾部节点删去,都要用到删除链表中某个节点这个操作。你想要删除链表中的某个节点,需要找到该节点的前驱节点和后继节点。对于寻找后继节点,单向链表和双向链表都能通过 next 指针在O(1)时间内完成;对于寻找前驱节点,单向链表需要从头开始找,也就是要O(n)时间,双向链表可以通过前向指针直接找到,需要O(1)时间。综上,要想在O(1)时间内完成该操作,当然需要双向链表.put 必须以 O(1)的平均时间复杂度运行显然只有链表能做到,并且我们选择双向链表实现。

2024-11-19 19:51:18 884

爱心.exe

爱心.exe

2022-11-16

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

TA关注的人

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