自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 JAVA知识点总结(复习自用)

每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。一块较小的内存空间, 是当前线程所执行的字节码的行号指示器,每条线程都要有一个独立的程序计数器,这类内存也称为“线程私有”的内存。JVM 内存区域主要分为线程私有区域【程序计数器、虚拟机栈、本地方法区】、线程共享区域【JAVA 堆、方法区】、直接内存。是被线程共享的一块内存区域,创建的对象和数组都保存在 Java 堆内存中,也是垃圾收集器进行垃圾收集的最重要的内存区域。5. 线程共享区域随虚拟机的启动/关闭而创建/销毁。

2023-10-25 00:40:05 68 1

原创 Leetcode刷题(四十二)

上面的方法就是简答粗暴地遍历,我就思考有没有可能优化一点速度,这里我可以选择把相同数字出现的次数记录下来,那么下面只要出现了互质的数字直接就增加对应的次数。比如说,前三个数字的第一位都是‘3’,那么后面只要有一个数字的最后一位是与‘3’互质的,最后的结果就可以直接增加3。这样就减少了一定的重复工作。它遍历数组 nums,提取每个数的第一个和最后一个数字,并检查是否存在之前遍历过的数字与当前数的最后一个数字互质。首先想到的就是使用双循环的暴力解法,使用双循环逐个遍历数组,找到所有的美丽下标对。

2024-06-20 21:13:47 285

原创 Leetcode刷题(四十一)

另外一个思路是最终我们要所有的0都在左边,所有的1都在右边,这样我们可以计算一个0的左边有多少个1,这样就可以算出将这些1移动到0的右边需要多少步(等于这个0左边1的数量),然后依次遍历完所有的0.这道题首先想到的就是双指针进行,设置两个指针放在字符串的开头和结尾,同时向中间遍历,这样会降低时间复杂度。这里的中心思想就是常说的贪心算法,每次遇到一个0,都要把遇到过的1放到他的右边,这就是要做到每一步的最优。这里由于我实际上进行了交换,导致时间复杂度升高,导致提交的时候时间超时,但是双指针的思路是正确的。

2024-06-06 19:42:38 163

原创 Leetcode刷题(四十)

最开始我是根据提示使用递归的方法来完成这个问题,然后在进行案例测试的过程中,发现如果使用暴力地使用逐个相乘的房法去递归的话,在幂次特别大的情况下,递归会导致程序的调用堆栈超出了它的限制。这里要使用的叫做快速幂算法,就是说,幂运算的过程可以看成是多个更小的幂运算过程相乘,那么怎么进行分割呢?这里就可以考虑对于幂次进行二进制的转换,因为二进制的的每一位的换算就是根据所在位置对2进行幂运算,所以对幂次进行二进制的转换,只要是1的位置就把该位置代表的次数与结果相乘。这样可以大大减少递归的层数。

2024-06-05 19:21:10 258

原创 Leetcode刷题(三十九)

这意味着如果键不存在,将会有两次哈希操作:一次是检查键是否存在,一次是实际的插入。然后为了优化细节,我使用了map.getOrDefault:这种方法会一次性返回与键关联的值,如果映射不包含该键,则返回默认值。这可能会减少哈希表的查找次数,因为即使是在添加新元素时,getOrDefault也会一次性完成所有操作。这道题的思路就是每一个词的字母组成是相同的,只是顺序不同,再进行排序之后,就可以形成相同的排序,就可以作为哈希表的key,把相同字母组成的字母异位词放在同一个key下。

2024-03-08 17:10:25 857

原创 Leetcode刷题(三十八)

这道题在我看来没有Medium的难度,他在算法上没有什么特别的地方,只要想明白矩阵旋转九十度的整个过程就很好想出解决方案。首先要明白矩阵旋转九十度就是把列变成行,同时进行反转。而矩阵的转置就是行列交换的操作,只不过并没有进行反转,只要再进行反转操作就可以。不论是转置操作还是反转操作都是很简单的,这里我直接给代码。

2024-03-07 17:02:41 233

原创 Leetcode刷题(三十七)

根据题意我们可以想到,在排列组合的过程中,每一层数字的确定可以看成从原来的所有数字中,取出一个放置在这一层的位置,依次向下一层放置,这里要注意的是每一层拿出来的数字不能相同,由于数组经过排序,所有重复的元素都是相邻的,只要将这次要拿的元素与本层上一次拿的元素比较是否相同即可。同时拿出的数字不能是之前曾经拿过的,这就是used这个数组的意义所在。全排列问题一般使用递归回溯的方法,由于要排除重复的排列组合,在开始之前,我们先对数组进行排序,这样做的目的是将相同的数字放在一起,便于后续步骤中跳过重复的序列。

2024-03-06 17:58:17 284

原创 Leetcode刷题(三十六)

如果是,说明需要进行下一次跳跃(因为无法再往前走了),此时count增加1,同时将end更新为max,即这一次跳跃后能达到的最远距离。由于i == end,进行一次跳跃,count = 1,更新end = 2。在每一次循环中,更新max变量为当前max和i + nums[i]中的较大值,其中i + nums[i]表示如果从当前位置i跳跃,能够达到的最远距离。第三次循环,i = 2,依然max = 4,且i == end,进行第二次跳跃,count = 2,更新end = 4。count用于记录跳跃的次数。

2024-03-02 16:16:05 264

原创 Leetcode刷题(三十五)

产生这种现象的原因是由于,在第一层的时候选择第一个元素为2,接下来是列出了全部其中有一个元素为2的组合,在下一个元素为3的分支中,如果下一个接着加入2这个元素,就一定会重复,因为其中有一个元素为2的组合已经在上一个2的分支全部被列了出来,所以3的分支就不需要考虑2的情况,后面以此类推,比如6的分支不需要考虑2以及3的情况。以题目中的示例1为例子,候选数组里有 2,如果找到了组合总和为 7 - 2 = 5 的所有组合,再在之前加上 2 ,就是7在2这个元素的所有组合;

2024-02-28 14:40:54 142

原创 Leetcode刷题(三十四)

这个字符串的生成思路使用的是递归的思想,这段代码使用了递归来生成“Count and Say”序列的第。递归的关键在于,它依赖于前一个成员来构建当前成员。每一步递归都会生成序列的下一个成员,直到达到所需的第。最终,当递归“展开”时,每一层的结果都会被用来构建最终的结果字符串,然后从最初调用的。这两个条件是递归的基本情况,不需要进一步递归就能给出答案。

2024-02-28 03:49:22 347

原创 Leetcode刷题(三十三)

由于条件为 false,执行异或操作 val ^ (1 << n):0000 ^ (1 左移 1 位),即 0000 ^ 0010 得到 0010(二进制),这是十进制的 2。例如,重置数字3的状态:marker ^= 1 << (3 - 1);执行异或操作 val ^ (1 << n):0010 ^ (1 左移 3 位),即 0010 ^ 1000 得到 1010(二进制),这是十进制的 10。board[3∗(i/3)+j/3][3∗(i%3)+j%3]表示了对固定的宫i,遍历格j(即每次检查一个宫)

2024-02-18 17:29:28 831

原创 Leetcode刷题(三十二)

这道题很简单,就是很直接的二分查找,具体二分查找的复习回顾,请看同专栏的上一篇文章。,有详细讲了二分查找的原理以及实现思路。

2024-02-01 15:51:03 245

原创 Leetcode刷题(三十一)

用查找开始位置举例,这里由于需要找到最开始的target的位置,所以需要不断的缩小查找范围,找到目标元素也要进行右指针范围的缩小而不是直接结束查找,这里对于右指针的范围进行缩小就可以实现不漏掉左边有可能出现的target最开始出现的位置。这里复习一下二分查找,二分查找是一种在有序数组中查找特定元素的高效算法。二分查找的效率很高,它的时间复杂度是 O(log n),其中 n 是数组的长度。在一个有序的数组中来查找位置,并且题目中要求了logn的时间复杂度,这就等于要求使用二分查找的方式来进行查找。

2024-01-31 14:49:55 414

原创 Leetcode刷题(三十)

这里我对算法做一下解释,由于上来先进行比较找到第一个右边大于左边的元素,这个就是交换的位置,原因是由于你从最后一个元素一直进行比较,所以后面的元素不满足条件就不会跳出循环,由此可知在第一个位置之前都是递减的序列,所以交换第一个增加的位置并不会漏掉其他情况。同时在调换完成之后,根据字典的大小序列可知,这一位已经是最靠近上一个序列的新序列,要想完全靠近,就要保证后面的序列是递增序列,由于前一步已经检查完,调换位置之后都是递减序列,所以直接进行序列反转即可。

2024-01-27 14:29:31 199

原创 Leetcode刷题(二十九)

我首先想到的是使用加减法,保留整数部分的除法可以看作是被除数减去整数个除数。我在根据这样的思路进行答题之后显示超时,这样计算对于比较大的数确实要花费大量的时间复杂度,这里就要使用一个方法叫做位移算法(也称为二进制除法)。使用位移方法进行的除法操作主要是逐步逼近被除数,直到无法再减去除数的任何倍数为止。处理符号:首先保存原始除数和被除数的符号,并使用它们的绝对值进行计算。计算部分结果:将被除数减去最后一次位移后的除数,将结果加到最终结果中。处理结果的符号:根据原始除数和被除数的符号,确定最终结果的符号。

2024-01-25 01:12:20 343

原创 Leetcode刷题(二十八)

KMP算法相关例题,同时复习KMP算法

2024-01-24 03:17:04 338

原创 Leetcode刷题(二十七)

这道题和上一道题很相似,是一道非常简单的题,根据题中的要求,并不能用另外的数组来储存,同时由于题目中强调不会检测新数组长度以外的后面的元素,所以思路就是使用双指针,一个指针(left)指定要更新元素的位置,另一个指针(right)遍历数组找到需要移除的元素。同时要考虑数组是否只有一个元素的情况,其实不用考虑数组没有元素的情况,这个情况如果发生直接返回数组长度为0就可以了。

2024-01-23 00:38:55 383 1

原创 Leetcode刷题(二十六)

这里我们使用双指针来进行数组元素的移动,首先定义一个左右指针(right、left),首先初始化left = 0、right = 1,然后将left与right进行比较,如果重复那么right直接右移跳过该元素,如果不同那么就把right的元素移动到left+1.不断重复。这道题由于是有序数组所以说重复的元素一定是相邻的,根据特所给的测试代码可以看出来,只要把非重复元素全部移动到数组的左侧,并不改变相对位置就可以完成这道题。它们更适合检查不应该发生的情况,而不是处理可能的错误情况。

2024-01-19 15:59:26 586

原创 Leetcode刷题(二十五)

这道题要求把每两个节点进行交换,如果只有一个节点或者没有节点就直接返回头结点。根据这个要求可以选择递归的方法来实现交换的功能,首先完成两个节点交换的功能,交换后把第三个节点作为头结点也传入这个函数进行递归,并把返回值赋给交换完成后的第二个节点的next。然后确定递归结束条件,第一个条件是判断是否传入的头结点为空节点,判断不是空节点之后再判断是不是之后只有头结点这个唯一的节点,满足以上两个之一就直接返回头结点结束递归。这里要注意要先判断head。

2024-01-17 14:27:27 494

原创 Leetcode刷题(二十四)

这道题可以使用动态规划的思想来进行实现,动态规划就是说首先确定dp数组的定义,然后找到递进关系式,再找到初始值,就可以获得所有的结果。这道题也是使用相同的思想,虽然没有使用dp数组来进行数据的记录,但是关系传递的思想是一样的。第三步:找到运算的初始值,从关系式可以知道,从第n个元素可以一直回推到第一个元素,所以你找到第一个元素就等于知道了所有的情况。第二步:找出数组元素之间的递进关系式,使用历史数据来找出下一步的数据,比如dp[n] = dp[n-1]+dp[n-2]。根据动态规划的思想,我们要想知道i。

2024-01-13 16:10:39 786

原创 Leetcode刷题(二十三)

在 Java 中,当一个整数的值超过其类型的最大值时,会发生称为“整数溢出”的现象。结果 result 将会是 -2,147,483,648(即 Integer.MIN_VALUE),因为 a + b 的真实结果 2,147,483,648 超出了 int 类型可以表示的范围,导致整数溢出。使用更大的数据类型:比如使用 long 类型,它有更大的范围(-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807)。这道题和本专栏前面的文章。

2024-01-10 17:58:02 929

原创 Leetcode刷题(二十二)

首先定义了列表conbination来储存结果,index代表遍历到那一层(也就是哪一个数字),递归函数中的循环条件i代表的是每个数字代表的字母个数,循环遍历数字代表的所有字母,然后和前面的数字所代表的字母组合起来,直到最后一个数字的字母完成组合,此时index的值应该等于数字数量,这就是递归跳出条件。不断进行确定前一个数字代表的字母,穷举下一个数字代表的字母,与前一个组合。在这道题中我是用递归来完成整个深度优先的遍历。这道题的笔记中记录的递归穷举三个数字的所有组合的原理是相似的。

2024-01-09 17:38:45 749

原创 Leetcode刷题(二十一)

根据这个粗暴的方法我发现,这道题主要有两个要注意的地方,一个是能用最大的数值来拆分就尽量用最大的(这就是贪心算法),第二个要注意的是从之前的代码中可以看出,900、400、90、40、9、4这几个数字和另外几个不一样,他们没有循环,最多出现一次,而其他的数字最多出现3次。这里根据第二条可以证明贪心算法在这里运用的正确性,由于最多只能出现的次数是三次和一次,所以使用贪心算法可以保证字符在这样的规则下使用数量最少。最开始的思路就是直接使用条件判断所有情况,直接按照位数进行拆解,但是时间复杂度会很差。

2024-01-07 16:08:47 339

原创 Leetcode刷题(二十)

break;} left ++;} right --;break;} left ++;} right --;Arrays;break;left++;right--;

2024-01-06 15:21:48 531

原创 Leetcode刷题(十九)

在我看了别人的方法后发现,java中自带一个方法String.startsWith(String s)来判断是否含有该前缀。并且我在查看这个函数时发现,这个函数的实现方法使用的也是字典树这个数据结构,所以我们可以把这个代码进行简化。字典树是一种用于存储字符串的树形数据结构,其中每个节点代表一个字符。那也就是说,数组本身的索引分别代表26个字母,索引所指位置存储的值代表了子数组所在位置。由字典树的性质可以知道,这道题中,要想字符串拥有最长公共前缀,那么说明我们要找到子节点数量为1的最长的路径。

2024-01-04 16:11:50 540

原创 Leetcode刷题(十八)

思考:这第二种思路的时间复杂度和空间复杂度要少很多,我觉得应该是出巡方式的问题,他根据Z字型的思想直接将字符串储存到 StringBuilder的指定位置,所以不需要一行一行进行合并。观察上图,其实是有规律的,PAYPAL 这6个为一组,ISHIRI 这6个为一组,这两组的每一位在求下一个位置的操作是一样的。我们定义 r2 = r1 + (r1 - 2);因为去掉最上面的一行,和最下面的一行,中间的是会出现的字符数量。当 mod >= 4 时,int next = i + 2 * (6 - mod);

2024-01-02 15:38:48 359

原创 Leetcode刷题(十七)

S(i, i+1) 这些状态中,即使有的状态的底边比 S(i, j) 长,但由于短板更短或不变,因此它们的容量不可能超过 S(i, j)。:假设在 S(i, j) 中 h[i] < h[j],则移动 i(即考虑 S(i+1, j))。, S(i, i+1))的短板要么和 S(i, j) 一样高,要么更短,且底边更短。:找到两个点 (i, h[i]) 和 (j, h[j])(其中 i < j),使得它们围成的矩形区域 (j - i) * min(h[i], h[j]) 最大。

2024-01-01 16:41:58 761

原创 Leetcode刷题(十六)

其实并不需要这么复杂,关于字符串的问题,其实在进行大小比较之后,并不需要合并字符串,找到合并后的符号对应的值,他其实直接可以使用自己本身代表的整数,只不过如果前一个数大于后一个数字的话,前一个数字直接乘以-1,也就是直接在总数上减去这个整数,这样并不需要那么多的没必要的数据结构,不管是判断还是循环都会少很多。刚看到题目之后,第一反应是使用哈希表以及队列来进行解答,在哈希表中将所有的罗马数字对应的整数存下来,然后将罗马数字放到队列中,对比前后元素的大小,通过合并字符串的形式,生成对应的key值。

2023-12-28 17:21:25 343 1

原创 Leetcode刷题(十五)

我们设定一个矩阵dp,boolean dp[l][r] 表示字符串从 i 到 j 这段是否为回文。试想如果 dp[l][r]=true,我们要判断 dp[l-1][r+1] 是否为回文。只需要判断字符串在(l-1)和(r+1)两个位置是否为相同的字符,是不是减少了很多重复计算。再向右对比,b=b,操作同上。状态转移方程,dp[l][r]=true 并且(l-1)和(r+1)两个位置为相同的字符,此时 dp[l-1][r+1]=true。初始状态,l=r 时,此时 dp[l][r]=true。

2023-12-27 19:27:15 317 1

原创 Leetcode刷题(十四)

我最先想到的就是最简单粗暴的考虑到所有的情况,然后不断地使用判断来进行功能的实现,将所有的情况都划分出来。这个方法费时费力,并且代码效率极其低下。但我还是就这么写完了。着重要注意int、long的大小范围。看了后面的解决方案,我了解到了自动机机制来改进代码。代码写得太垃圾了我都不太想放出来。暂时还没看明白,等有空再研究。

2023-12-25 17:33:16 23

原创 Leetcode刷题(十三)

没什么思路,是看别人的解答方法写出来的,甚至有一些细节也没弄明白,主要的思想就是设立dp矩阵是用动态规划,动态规划之前的题也用过。但是这道题主要的难点在于各种情况的归纳。

2023-12-25 13:56:18 69

原创 Leetcode刷题(十二)

代码中有很多重复的部分,比如左右括号的比较,都可以封装到一个函数中进行重复使用可以使得代码更加简洁美观。注意声明堆栈的数据类型(String的堆栈无法储存char类型的字符,要使用Character类型的堆栈)。

2023-12-23 16:41:11 33 1

原创 Leetcode刷题(十一)

使用递归的方法来实现链表的创立,将两个链表的每个节点相加。注意要考虑两个链表相加的时候的各种情况,包括:是否进位、链表是否结束遍历,链表遍历结束后是否存在进位(若存在则进位创建新结点)。

2023-12-22 17:03:54 18

原创 Leetcode刷题(十)

本问题如果使用两次遍历可以十分简单的解决,但是题目中要求了使用一次遍历那么就要想一些办法。这里我想到的是使用双指针。设置两个指针,让两个指针之间保持固定的距离使得两个指针同时进行遍历,直到后一个指针指向空,那么前一个指针的下一个结点就是目标结点。但是如果直接从提供的链表的头结点开始,假设链表只有一个结点,那么前一个指针的下一个结点就不是目标结点,这就大大增加了代码的复杂程度。所以我设置一个虚拟头结点,使得虚拟头结点的下一个结点是实际的头结点。

2023-12-21 15:57:36 26

原创 Leetcode刷题(九)

element 参数是要添加到列表中的元素。index 参数是元素要被插入的位置的索引。如果在指定的 index 位置已经有元素存在,那么现有的元素(以及该位置之后的所有元素)会被向后移动,为新元素腾出空间。因此,新元素被插入到指定的位置,原来的元素不会被覆盖,而是向后顺延。这里的 1 被插入到索引位置 1(列表中的第二个位置,因为索引是从 0 开始的),原来索引为 1 的元素 3 和之后的元素 4 都向后移动了一个位置。

2023-12-20 17:14:05 18

原创 Leetcode刷题(八)

首先对数组的元素进行遍历,找到‘1’的元素,把这个元素当作树这个结构的根节点进行深度优先遍历(这里可以是用递归的思想,可以参考二叉树,而这里的二维数组可以看作是有上下左右四个子树的四叉树),在遍历的过程中如何确定遍历到的元素属于一个岛屿呢,我这里把遍历到的位置设置为0,也就是说,我每遍历到一个岛屿,就把一个岛屿设置成为大海(设置为零)。所以我在遍历整个数组的过程中时,每遇到一个‘1’,岛屿数量就加一,然后将所有属于该岛屿的‘1’变为‘0’。

2023-12-19 16:25:15 33 1

原创 Leetcode刷题(七)

Arrays.copyOfRange():这个方法是Java标准库中的 java.util.Arrays 类的一部分,它可以用来从原始数组中复制指定范围的元素到一个新数组Arrays.copyOfRange() 的第二个参数是开始截取的起始索引(包含),第三个参数是结束索引(不包括)。如果结束索引超过了原始数组的长度,那么在新数组中超出部分的元素将会被设置为0(对于数值类型)或 null(对于对象类型)。

2023-12-07 23:32:55 26 1

原创 Leetcode刷题(六)

队列操作// 添加元素 queue . offer(1);// 查看元素 System . out . println("Head of queue: " + queue . peek());// 移除元素 System . out . println("Removed element: " + queue . poll());

2023-12-03 22:04:14 23 1

原创 Leetcode刷题(五)

开始想要使用类似冒泡排序,将第一个元素不断与后面相邻的元素交换位置,最后沉底,然后再从新链表的第一个开始沉底。但是这样写不仅会有至少两层循环,而且循环的条件以及头节点的地址都不好写。我直接将节点的指针逐个进行翻转,并使用一个新的指针记录未反转的部分,这样节点的位置不变只是指针的指向反转,最后的头节点就是原来链表的最后一个节点。这样只需要一个循环而且新链表的头节点很好表示。

2023-11-22 02:42:46 28

原创 Leetcode刷题(四)

这样的话可以根据三个数字的加和结果进行指针的移动,如果结果大于零,说明元素过大则指针right左移,如果结果小于零,说明元素过小则left右移,如果结果等于零,则将数字保存与答案中,并请跳过相同的元素(保证输出不重复)。一开始准备使用简单粗暴的三层循环进行解答,但是提交发现超时,所以不得不进行优化。优化就要减少循环的数量,首先将数组变成有序的数组,这样相同的数字就会排列在一起,可以有效避免重复三元组的出现,同时因为求和的需要,有序的数组可以根据求和的结果来判定指针的移动。

2023-11-21 00:22:37 49 1

空空如也

空空如也

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

TA关注的人

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