- 博客(30)
- 收藏
- 关注
原创 day15 leetcode-hot100-29(链表8)
(1)将链表中所有节点都加入到哈希表中,其中哈希表的格式为HashMap<Integer,ListNode>,前面表示节点的位置,后面是节点。设计快慢指针,其中快指针比慢指针多走n次,等快指针到尾部的时候,慢指针所在的位置就是要弹出的位置。(2)根据(1)可以知道链表的总长度nums,倒数第n个节点的位置为del=nums-n+1;(3)然后取出del-1与del+1位置的节点,让del-1的下一个节点为del+1即可。(2)然后再次遍历链表到L-n的位置,直接让该指针的节点指向下下一个即可。
2025-05-31 16:35:11
1334
原创 day15 leetcode-hot100-28(链表7)
(2)链表1与链表2相加,具体方式为sum=n1+n2+jin(进位),该位置的值为sum%10,jin=sum/10.(4)最后如果进位不为0,则需要再增加一个节点,节点值为jin(进位值)(3)判断两个链表的下一个节点是否为空,不为空就向下继续走。最核心的一点就是将两个链表模拟为等长,不足的假设为0;(1)设置一个新链表newl来代表相加结果。
2025-05-31 15:44:40
145
原创 day14 leetcode-hot100-27(链表6)
创建空节点:ListNode n1 = new ListNode(-1);创建一个空节点,用来组装这两个链表,谁小谁就是下一个节点。
2025-05-30 20:42:14
380
原创 day14 leetcode-hot100-25(链表4)
将节点一个一个加入HashSet,并用contains判断是否存在之前有存储过的节点,如果有便是环,如果没有便不是环。一个慢指针每次走1格,一个快指针每次走2格,如果存在环肯定会相遇,如果不存在,最后都为null.优化空间复杂度为O(1)
2025-05-30 16:41:27
218
原创 day13 leetcode-hot100-24(链表3)
arraylist的长度函数:list.size()将后半段链表反转,然后进行比较。取单链表的中间节点:快慢指针。将链表转化为列表进行比较。
2025-05-29 21:38:21
234
原创 day13 leetcode-hot100-23(链表2)
方法就是将指针(next)指向前一个节点即可。我们设置old为前一个节点,current为当前节点,也就是让current.next=old即可。链表由多个节点构成,每个节点包括值与指针,其中指针指向下一个节点(单链表)。这个题目很简单,最主要的就是了解链表的数据结构。
2025-05-29 20:29:01
197
原创 day13 leetcode-hot100-22(链表1)
以上述结论为基础,我们可以判断节点A与节点B是否相等,如果相等则返回,如果不相等最后都输出null,然后结束。(2)我们用两个指针分别从A链与B链开始遍历,如果遍历到尾部就从另一条链再遍历。(1)如果A和B相交,那么假设相交的部分为c,不相交的部分分别为a和b。(3)以A链为例,其走过的路:a+c+b再次到c。(4)以B链为例,其走过的路:b+c+a再次到c。(1)将A链的所有数据存储到HashSet中。(2)遍历B链,找到是否在A中存在。
2025-05-29 12:49:52
234
原创 day12 leetcode-hot100-21(矩阵4)
因为每行都是递增的,每列也是递增的,所以我们可以选择从右上角开始遍历,遇到大于target的那就向左走,遇到小于target那就向下走。思路:每行都用二分查找,因为每行都是排好序的。思路:两层for循环即可。
2025-05-28 16:49:13
413
原创 day12 leetcode-hot100-20(矩阵3)
(1)这个很有意思,你可以旋转四次试一试,能够发现规律,也就是第四次旋转到原来的位置了,那我们就可以将第一次开始旋转的位置放到临时变量temp中,然后依次替代即可。思路:很简单,新建一个二维数组,直接找新数组与旧数组的规律即可。那就是相当于 new[col][n-row-1]=old[row][col],然后两个for循环,分别为0-(n-1)即可。(2)难点在于如何遍历,肯定不能遍历n*n次了,否则就回去了,我们现在是每个循环改变4次,所以只需要循环n*n/4即可。
2025-05-28 15:44:38
430
原创 day12 leetcode-hot100-19(矩阵2)
(2)为什么count=flag-1的时候还需要再加入一个元素,因为我这个循环代码设计的原因,每次都取不到当前方向的最后一个值,导致在最后一个元素永远取不到,所以就人为补充最后的元素。(1)设计上下左右方向控制器以及边界。比如zy=1向右,zy=-1向左;sx=1向上,sx=-1向下。上边界0,下边界hang-1,左边界=0,右边界=lie-1。(1)为什么我一开始上边界为1,因为一开始就向右移动,说明以及来到过上边界一次了,所以优先进行收缩一个单位。(2)然后根据是否到达边界,来改变方向与边界。
2025-05-28 12:15:20
386
原创 day11 leetcode-hot100-18(矩阵1)
(1)为了不额外创建数组,将第一行与第一列作为标记数组,但是要提前将第一行与第一列是否为存在0先进行标记。其余思路与方法2一致。(2)然后用标记数组作为判断条件,再双层for循环判断该位置是否为0.判断方法是该行或该列是否被标记。这个题暴力法也很容易理解,直接双层for循环找到0的位置,然后在双层for循环置零。(1)设计两个行数组与列数组,标记遍历每个0所在行与列。
2025-05-27 21:54:45
387
原创 day11 leetcode-hot100-17(普通数组3)
方法2我们是用两个标记数组表示左侧乘积与右侧乘积,但这样占用O(N)的空间,怎么能减少空间复杂度呢?方法很简单,就是直接用返回值ans直接作为标记数组,比如左累乘数组,然后在乘以右的时候直接用即可。暴力法很简单,两层for循环即可,除了本身的不做相乘,其余的相乘作为答案。用两个数组分别表示i左右两侧的累计乘积,与leetcode。
2025-05-27 21:33:56
338
原创 day11 leetcode-hot100-15(普通数组3)
理论:我们可以设想一下,轮转k位,也就是将后k位的数放到最前面,前面0到k-1放到最后面。我们直接反转数组,然后在分两段再次反转不就正好完成轮转了吗?这个更容易,新建一个数组即可。
2025-05-27 20:05:26
169
原创 day11 leetcode-hot100-13(普通数组1)ps:子串
(1)设置一个数组f,数组f的每个位置,代表以该数为最后1位的最大子串和。(2)最后取f(i)的最大值即可。这个题目是比较典型的动态规划。也是代表子串的一个形式。
2025-05-27 10:36:04
149
原创 day10 leetcode-hot100-12(子串系列3)
(1)子串题目经常用哈希表HashMap/HashSet来代表子串,这样可以不用substring函数获取子串,因为substring函数时间复杂度为O(r-l).ps:为了让子串最小,需要设置一个minlen,只有新子串长度小于之前获得的子串的长度时才更新答案的左右边界。(3)然后r指针再开始移动,找到下一个包含t所有字符的子串,以此类推。(1)右指针r一直向后走,直到找到包含所有字符串t的子串。滑动窗口中的快慢指针来解决,右指针r扩展,左指针l收缩。(2)左指针开始移动,直到该子串不能在缩小。
2025-05-26 22:31:52
309
原创 day10 leetcode-hot100-11(子串系列2)
这道题题目用优先队列很好理解,就是维护一个大根堆,堆顶是当前窗口中最大的元素,每次移动取堆顶元素即可。ps:堆的插入和删除是logk复杂度。与上面思路类似,也是维护一个窗口,只不过这次窗口是单调的,因此只需要和最后的比较即可,时间复杂度为O(1).
2025-05-26 17:42:19
406
原创 day9 leetcode-hot100-10(子串系列1)
从这次的算法开始,我不打算写具体的暴力算法了,突然感觉没有意义,也可能会导致惯性思维,只是简单写一下思路。(但不是完全不考虑,因为还需要从中想出来思路,进行优化)
2025-05-25 22:45:02
243
原创 leetcode-总结1-哈希表+双指针+滑动窗口
虽然就做了9道题目,但还是想要记录一下,方便以后自己查找,肯定写的非常差。希望大佬能给我一些修改建议,这些方法/思路有哪些具体的应用场景/作用?
2025-05-25 16:40:28
923
原创 day9 leetcode-hot100-9(滑动窗体系列2)
对于这个题目,我们可以维护一个滑动窗口,比较每个窗口与字符串p是否为异位字符串。与之前一样,先写一个函数判断两个字符串是否为异位字符串,然后从i=0,遍历全部的子串即可。(2)字符数组转字符串String str = new String(char[]);(1)用统计每个窗口的26个字母数进行比较O(m),而不是排序O(m*log m)。(2)窗口用数组或左右指针来确定,而不是substring函数(O(r-l))(3)字符串比较 if( s1.equals(s2) );
2025-05-25 13:17:57
530
原创 day7 leetcode-hot100-7(双指针系列4)ps:栈也能做记得补充
(2)指针的移动方式是比较确定的,如果height[left]>height[right],说明right位置左侧的最大值left_max一定大于等于右侧的最大值right_max.那么就直接确定了该位置两侧最大值的较小值。除此之外,还需要确定每个位置i有多少蓝色符合的,也就是每个位置i两侧的最高值中的较小的减去当前的高度。根据上面的分析可知,我们的目的就是为了确定每个位置i能存多少水,进而需要知道该位置i两侧最高值的较小值,那么除了用数组记录,还有什么办法吗?题目是双指针,肯定还需要用双指针解决一下。
2025-05-22 16:57:46
375
原创 day6 leetcode-hot100-6(双指针系列3)
根据双指针的作用,可以将遍历两个元素,转化为双指针的方法,为了防止重复(也就是类似(0,1,-1)与(-1,0,1)的情况),需要先进行排序,保障第一层循环的数小于等于的二层的数,二三层同理。由于已经排序完成,就可以将第一层循环值的负数作为目标,左指针与右指针分别在两侧,两者对应的数组之和,记为sum,如果小于target,则l++,如果大于target,则r--;「双指针」作用是当我们需要枚举数组中的两个元素时,如果我们发现随着第一个元素的递增,第二个元素是递减的,那么就可以使用双指针的方法。
2025-05-21 16:41:03
1469
原创 day4 leetcode-hot100-4(双指针系列1)
(1)目的就是将数组中的所有零放到最后,直接创建一个新数组,将所有不是零的值按原顺序保存,而且时间复杂度还是O(N)。找到最近的非0的位置,然后交换值。(ps:除了一开始l指定的不一定是0,但以后全是0,l-r之间的数也全都是0.)暴力就是模拟冒泡排序,将数组中所有的0,一位一位移动到最后。位置,如果0下面的紧挨着的数字还是0,那么位置i不能+1,需要再次向后移一轮。总之,慢指针L是找0的,R指针是找到最近的非0,然后交换位置。,请题目忽略最后一句话的要求挠头😜)找到0的位置,快指针。
2025-05-19 15:16:49
319
原创 day3 leetcode-hot100-3
(2)新的数组要找到最长的序列,大概率是一层for,然后嵌套一个for,判断每个数字开头最长的序列数,最后取最大值。(3)如果是,用while计算num开头的序列长度:还是用contains方法判断是否存在num+1,如果存在就+1,每次循环结束就和最长的比较一下。关键就是判断数num是否为开头,方法很简单,就是查看HashSet中是否存在num-1,如果存在就不是,如果不存在就是开头。简单来说就是判断这个数是不是某个序列的开头,如果是就进行计算,找到该序列的长度,如果不是,那就跳过。
2025-05-18 12:36:09
465
原创 day2 leetcode-hot100-2
(7)获取新建:ArrayList<String> list =map.getOrDefault(key,new ArrayList<String>());(1)列表初始化:List<List<String>> res = new ArrayList<>;(5)字符转换为数值:int value =(int) str.charAt(i);(4)字符升序排序,会改变原来的:Arrays.sort(chars_a);(3)判断函数的写法:我是简单的计算值(存在逻辑问题)或排序。(1)char-char是整形。
2025-05-17 16:46:15
936
原创 day1 leetcode-hot100-1
因为找target-x的复杂度也是O(N),哈希表的查找与插入复杂度是O(1),所以用哈希表。初始化:HashMap<Integer,Integer> map = new HashMap<>();判断是否存在Key/Value:map.containsKey(Key/Value)添加:map.put(key,value);获取:map.get(key);1.暴力题解(O(n*n))
2025-05-14 22:44:54
199
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人