- 博客(169)
- 收藏
- 关注
原创 【笔试】 网易雷火校园招聘笔试编程题类型
动态规划:编辑距离、打家劫舍、最长回文子串等经典问题(需掌握状态转移方程优化)。字符串处理:加密解密、模式匹配、复杂模拟题(如文本编辑器)。图论与搜索:BFS/DFS在路径问题或状态模拟中的应用。数学与数论:质因数分解、欧拉函数、数位DP(如最小F(x)=φ(x)/x问题)。
2025-05-10 07:00:00
955
原创 【Hot 100】200. 岛屿数量
递归终止条件顺序:先判断坐标合法性,再访问数组,确保不会越界。空间优化:直接修改原数组,无需额外空间。扩展性:若需保留原数组数据,可创建visited数组记录访问状态。你的代码已经正确实现了核心逻辑,上述优化可根据实际场景选择应用。
2025-05-10 07:00:00
424
原创 【Hot 100】236. 二叉树的最近公共祖先
这个解法在大多数情况下工作良好,但如果追求更优的解法,可以考虑一次遍历同时查找两个节点的公共祖先,这样可以将时间复杂度优化到单次遍历。代码思路是正确的,通过分别找到从根节点到p和q的路径,然后比较这两条路径来找到最后一个公共节点。在查找二叉树路径的时候,在递归完左右子树后,还需要再判断刚才左右子树是否找到路径,找到路径的话直接返回才行。初步的思路,找出从根节点到这两个节点的路径,然后遍历这两个路径判断第一个公共的节点是谁。从今天的题目来看,自己在遍历路径方面还有些不熟练,要再多练习。
2025-05-09 07:00:00
1033
原创 【Hot 100】124. 二叉树中的最大路径和
区分节点的"贡献值"(返回给父节点)和"完整路径值"(更新全局最大值)贡献值只能选择一边(左或右),而完整路径可以包含两边负贡献值被舍弃(取0)这种分治法的思路非常经典,理解后可以解决许多类似的树形DP问题。
2025-05-09 07:00:00
445
原创 【Hot 100】114. 二叉树展开为链表
你的优化解法是正确的,利用了后序遍历的特性,实现了原地修改。它的时间复杂度是 O(n),空间复杂度是 O(h)(递归栈的深度,h 是树的高度)。对于大多数情况,这是一个非常优雅的解法!
2025-05-08 07:00:00
675
原创 【Hot 100】105. 从前序与中序遍历序列构造二叉树
当前你在每次递归时都线性搜索根节点在中序遍历中的位置,这会导致时间复杂度较高(最坏情况下为O(n^2))。可以使用哈希表(unordered_map)预先存储中序遍历的值和索引,这样可以将查找时间降到O(1),整体时间复杂度优化到O(n)。总结:递归的逻辑其实不复杂,每次都通过前序和中序数组构建当前的根节点,然后递归构建左右子树即可。不过,还有一些可以优化的地方,特别是在查找中序遍历中根节点索引的部分。:虽然题目保证输入合法,但在实际工程中,可以添加一些检查(如前序和中序数组长度是否一致)。
2025-05-08 07:00:00
1195
原创 【Hot 100】437. 路径总和 III
可以考虑使用前缀和的方法来优化时间复杂度到O(n),通过哈希表记录路径上的前缀和,从而快速计算是否存在满足条件的子路径。题目要求我们找出二叉树中所有路径,这些路径上的节点值之和等于给定的目标值。这里的路径不需要从根节点开始,也不需要在叶子节点结束,但必须是从父节点指向子节点的方向。这道题的关键在于如何高效地遍历所有可能的路径,并计算它们的和是否等于目标值。这道题目看着有点难,需要找出所有的路径,遍历路径的话可以采用递归+回溯来实现,将每一种路径添加到路径集合中。,然后在递归左右子树时传入的是。
2025-05-08 07:00:00
580
原创 【Hot 100】98. 验证二叉搜索树
原始代码问题:空间复杂度高,未处理边界。推荐优化方法1:递归中序遍历,实时比较前驱节点。方法2:迭代法,进一步优化空间。选择建议:优先使用方法1,代码简洁且高效;若树深度较大,考虑方法2。
2025-05-07 07:00:00
739
原创 【Hot 100】230. 二叉搜索树中第 K 小的元素
递归调用会有栈空间的开销,尤其是当树很高时可能导致栈溢出。可以用迭代(显式栈)实现中序遍历,同样支持提前终止。但是其实可以在中序递归遍历的时候记录一下当前遍历了几个元素,可以用全局变量记录也可以用引用传参记录。可以通过成员变量或全局变量替代,减少递归函数的参数传递。但这样会牺牲一定的封装性,需权衡。这道题目最暴力的解法就是中序遍历结果保存在数组里面然后直接通过索引值返回。通过中序遍历(左-根-右)来找到二叉搜索树(BST)中第。BST 的中序遍历结果是一个升序序列,因此第。个被访问的节点就是第。
2025-05-07 07:00:00
827
原创 【Hot 100】199. 二叉树的右视图
另一种思路是从左到右public:if (!while (!// 记录每层最后一个节点return res;
2025-05-07 07:00:00
1190
原创 【Hot 100】102. 二叉树的层序遍历
你的原始代码已经足够高效,优化空间有限。如果追求极致性能,可以考虑提前分配cur的空间(但对小规模数据影响不大)。其他优化(如std::move)更多是编码习惯,实际性能提升可能不明显。保持当前写法也是完全合理的!
2025-05-06 07:00:00
732
原创 【Hot 100】108. 将有序数组转换为二叉搜索树
你的原始代码已经非常高效,主要优化点是避免整数溢出(虽然LeetCode的测试用例可能不覆盖此场景)。其他优化(如迭代法)可能增加代码复杂度,但实际收益有限。保持当前递归写法是推荐的做法,清晰且易于维护。
2025-05-06 07:00:00
988
原创 【Hot 100】101. 对称二叉树
树的问题常考虑递归:许多树的问题都可以通过递归优雅地解决。不能仅依赖遍历结果:树的遍历序列会丢失结构信息,需要谨慎使用。对称性的本质:理解对称二叉树的定义是关键——不仅是值对称,结构也必须对称。这个题目教会我们,有时候看似简单的题目需要深入理解问题的本质才能找到正确的解决方法。
2025-05-05 07:00:00
615
原创 【Hot 100】543. 二叉树的直径
方法时间复杂度空间复杂度关键优化点原始解法(双重递归)O(n²)O(h)每个节点都重新计算深度,导致重复计算优化解法(后序遍历)O(n)O(h)在计算深度的同时更新直径,避免重复计算核心思想:后序遍历保证我们先知道左右子树的深度,再计算当前节点的深度和直径。全局变量记录遍历过程中出现的最大直径。这样,我们只需要一次遍历就能高效解决问题!🚀。
2025-05-05 07:00:00
667
原创 【Hot 100】104. 二叉树的最大深度
可能有些疑惑,为什么上一个二叉树的题目需要重新创建一个递归函数来实现,而这道题就可以直接将这个核心函数作为递归函数。因为该核心函数的返回值是整型(int),整形的数据可以很方便的相加。,最终需要合并多个子树的遍历结果(左子树 + 根节点 + 右子树)。通过这种对比分析,可以更深刻地理解递归设计的灵活性。:中序遍历需要返回一个包含所有节点值的。中需要额外定义一个辅助递归函数(如。下面我们详细对比两者的差异。计算,合并操作是 O(1)。所以可以直接作为递归函数。问题中可以直接用原函数(,每次递归会生成独立的。
2025-05-04 07:00:00
1778
原创 【Hot 100】226. 翻转二叉树
递归思想:将问题分解为翻转左右子树的子问题。临时变量:必须用tmp保存右子树,否则在修改后会丢失原右子树的引用。终止条件:处理空节点是递归的基础情况。解法是完全正确的,且代码清晰。通过临时变量tmp保存右子树是关键步骤,确保了交换的正确性。递归方法在此类问题中既自然又高效,适合作为首选解法。
2025-05-04 06:45:00
829
原创 【Hot 100】94. 二叉树的中序遍历
前中后序遍历可以通过递归写出清晰的代码,当然也可以通过栈来写出非递归的代码。作为一个递归函数来写的话,就需要处理这个返回值,要考虑如何将这个返回值合并。中递归,每次递归调用会返回一个独立的向量,需要将这些向量合并(如拼接左子树、当前节点、右子树的结果),效率较低。然后函数有一个返回值,这个返回值记录的是二叉树的值。,这个函数没有返回值,但是使用了引用传递来让这个结果合并起来。中,无需合并操作,既简化了代码,又保证了线性时间复杂度。下面来解析一下我的代码,本题给出的核心函数是。因此,我引入辅助函数。
2025-05-03 16:43:49
701
原创 【Hot 100】 146. LRU 缓存
目的:创建存储数据的基本单元int key;// 用于删除尾节点时反向查找哈希表int value;Node* prev;Node* next;双数据结构协作哈希表:O(1) 时间查找双向链表:维护访问顺序伪节点的妙用消除头尾节点的特殊判断统一所有节点的操作逻辑操作原子化将链表操作分解为独立方法提高代码可读性和可维护性内存管理淘汰节点时需手动释放内存插入新节点时动态分配内存通过这种分步实现方式,可以更清晰地理解每个组件的作用,也便于在开发过程中逐步测试验证每个功能的正确性。
2025-05-03 15:28:52
1182
原创 【Hot 100】23. 合并 K 个升序链表
虽然是一个困难题,但是其实可以把问题拆分一下,每次都合并两个有序链表,然后循环从前往后合并即可。然后合并两个有序链表在前面已经写过了。你的解法是顺序合并两个链表的方法,虽然正确但效率可以优化。你的原始解法可以轻松升级为分治合并方案,只需修改合并策略即可获得显著性能提升。将k个链表两两分组合并,再合并结果,时间复杂度O(kn logk)使用优先队列每次取出最小节点,时间复杂度O(kn logk)调整合并顺序,减少重复遍历。
2025-05-01 07:00:00
900
原创 【Hot 100】 148. 排序链表
今天的题目是对链表进行排序,所以我先简单回顾一下十大排序算法的基本思想以及C++代码实现。基本思想:重复地遍历要排序的数列,一次比较两个元素,如果顺序错误就交换它们。每次遍历后,最大的元素会"冒泡"到最后。2. 选择排序 (Selection Sort)基本思想:每次从未排序部分选择最小(或最大)的元素,放到已排序部分的末尾。3. 插入排序 (Insertion Sort)基本思想:将未排序部分的第一个元素插入到已排序部分的适当位置。4. 希尔排序 (Shell Sort)讲解视频(这个视频讲的
2025-04-30 13:26:08
1578
原创 【Hot 100】138. 随机链表的复制
难点是 random 的节点索引如何确定。用一个哈希表记录当前节点以及当前节点的索引。然后在可以快速的查找当前节点的random指向的是哪一个索引。但是这样空间复杂度太高了。要优化代码,关键在于减少遍历次数和简化数据结构。我们可以通过使用哈希表直接映射原始节点到新节点,从而省去索引和向量的使用,将三次遍历合并为两次遍历。这种方法将时间复杂度保持在 O(n),空间复杂度为 O(n)(哈希表存储所有节点),但代码更简洁高效,减少了不必要的遍历和数据存储。思路有点复杂,但是还是顺利写出来了。
2025-04-30 07:00:00
581
原创 【Hot 100】25. K 个一组翻转链表
要解决这个问题,我们需要每k个节点为一组进行反转链表,如果剩余的节点不足k个则保持原样。关键在于正确处理每一组的反转,并正确连接各组之间的节点。下面这个是正确的代码,其实我看着思路是没有变化的,但是不知道为什么我的就错误了。还得再回来仔细看一遍。这种方法确保每组节点正确反转,并正确连接各组之间的节点,时间复杂度为O(n),空间复杂度为O(1)。这道题思路确实不难,就是在处理 k 个一组的链表链接时有些复杂。我的解题可以通过一部分例子,我也不知道为什么。
2025-04-29 11:37:14
850
原创 【Hot 100】 24. 两两交换链表中的节点
其实这道题目也不难,就是要画图理清楚节点指向修改的顺序,以及这四个指针应该如何移动。通过精简变量和统一循环条件,代码逻辑更清晰且覆盖所有边界情况。
2025-04-29 07:00:00
592
原创 【Hot 100】 19. 删除链表的倒数第 N 个结点
通过移除冗余判断和优化循环结构,代码逻辑更加清晰且鲁棒,确保在所有合法输入下正确处理节点删除。
2025-04-28 13:00:34
928
原创 【Hot 100】2. 两数相加
如果要通过遍历一次来解决,就需要考虑两个节点相加大于10的情况,此时需要给下一个节点进一。两个链表都从头部开始遍历,然后计算两个节点相加的值是否大于10,大于10的话(使用一个bool变量来标识)下一个节点的值要加一。感觉这道题目做法还是挺多的,暴力解法就是将两个链表的数字先计算出来,然后再使用这个数字来构造链表,这样就不用考虑,两个节点相加后大于10需要进一的情况了。今天继续写链表的题目,写多了就能发现要善于使用指针,比如虚拟头结点。好像并不需要栈这个结构,直接相加后构建新的链表即可。
2025-04-28 12:32:22
435
原创 【Hot 100】 21. 合并两个有序链表
我自己的代码没有通过,但是思路好像没有问题就是在节点的移动处理时有错误。下面的是根据正确的代码再写了一遍。解决了这两个核心问题。这是处理链表合并问题的标准范式,建议掌握这种设计模式。继续链表题目,总感觉这道简单题并不简单。这道题后面还得再重新写一遍。当某个链表遍历完时,另一个链表的剩余节点没有被连接到最终链表中。),导致每次只能操作当前两个节点,无法维护整体结构。时,直接覆盖原有指针,导致原链表后续节点被切断。您缺少一个始终指向合并链表末尾的指针(如。
2025-04-27 12:28:45
541
原创 【Hot100】142. 环形链表 II
所以在两个指针相遇后,再次将慢指针置为链表起始位置,然后将快指针的移动速度减为1,然后两个指针同时出发并相遇时就是链表的环入口处。您原来的实现已经正确,这些改动主要是代码风格上的改进。由于前面刷过这道题了,所以知道这道题是使用快慢指针,然后再画图得到一定的数量关系,可以找出链表环的入口节点。n表示快指针走过的环形的圈数,是1到无穷大范围,根据快慢指针的行走速度可以得到。上一个题目是判断链表是否是环形,这次是需要找出环形链表的入口,如果不是环形链表则返回空。的距离,而快指针走了。,也就是t的距离等于。
2025-04-27 11:13:59
1006
原创 【Hot100】141. 环形链表
你的原始代码是正确的,但可以更简洁。优化后的代码逻辑更清晰,减少了冗余判断,同时保持了相同的时间复杂度(O(n))和空间复杂度(O(1))。
2025-04-22 07:15:00
879
原创 【Hot100】 234. 回文链表
看了下优化空间的解法,原来是先翻转后面的链表然后再比较,我觉得没必要,因为这样修改了原始链表的数据。直接用额外的空间来解决就好了。
2025-04-22 07:00:00
259
原创 【Hot100】206. 反转链表
这道题目还是很基础的,做的时候没有什么问题。我觉得有一点容易混淆:要分清楚指针指向的节点和节点的next指针指向的下一个节点的区别,因为在画图的时候会发现,节点next指向的节点用一个箭头表示,然后指针指向一个节点也是用箭头表示的。以下面这个示意图为例,1 2 3 4 之间的箭头表示的是当前节点的next指针的指向。然后 Pre Cur 指针的箭头是当前指针指向的节点。
2025-04-21 10:34:33
504
原创 【Hot100】 240. 搜索二维矩阵 II
这种贪心搜索法是解决此类二维矩阵搜索问题的最优方法之一,既高效又直观。有三种方法,只想到了前两种,第三种没有想到。:从矩阵的右上角(即第一行最后一列)开始搜索。
2025-04-20 11:29:06
870
原创 【Hot100】 48. 旋转图像
要将一个 n × n 的二维矩阵顺时针旋转 90 度,并且原地修改(即不使用额外的矩阵),可以采用分层旋转的方法。通过这种方式,矩阵被原地顺时针旋转了 90 度,无需额外的存储空间。也不知道自己怎么想到这个规律的,总是很神奇。
2025-04-20 07:00:00
916
原创 【Hot100】54. 螺旋矩阵
虽然写出来了,但是代码也写的太丑陋了,感觉逻辑不清晰。但是其实我看了下官方题解,我的这个代码也不算是很复杂,虽然内容多,但是其实还是好理解的。按照右→下→左→上的顺序处理,每次处理完一个方向后立即检查是否需要终止循环,避免无效遍历。这种方法减少了冗余的条件检查,逻辑清晰,且避免了复杂的索引调整,提高了代码的可读性和健壮性。分别表示当前未遍历区域的上下左右边界。每次处理完一个方向后,收缩对应的边界。每个方向的遍历使用明确的起点和终点,无需手动调整索引位置,代码更直观。,确保存在未遍历的元素。
2025-04-19 11:56:44
279
原创 【Hot100】 73. 矩阵置零
核心思想:利用首行首列作为标记位,避免额外空间。关键顺序先记录首行首列的原始状态。再标记其他行列。最后处理首行首列。避免覆盖标记:首行首列的原始0必须在标记完成后处理,否则标记会被破坏。public:// 检查矩阵是否为空// 行数// 列数// 标记第一行和第一列是否需要置零(因为它们会被用来记录其他行列的状态,需要最后处理)// 第一行是否需要置零// 第一列是否需要置零// 检查第一行是否有0(注意:单独处理,避免后续覆盖标记)j < n;++j) {
2025-04-19 10:50:47
1293
原创 【Hot100】41. 缺失的第一个正数
方法一:对数组进行排序,时间复杂度O(nlogn),然后遍历排序后的数组,跳过负数和0值,然后判断第一个遇到的正值是否是1,如果不是1,则输出1作为结果,如果是1继续往后遍历是否是2 3 4 5。如data[i]标识i+1的数值是否出现,通过再遍历一次数组来填充。我们需要一个时间复杂度O(n)且空间复杂度O(1)的算法。考虑到数组本身可以用于存储信息,可以尝试“原地哈希”或“索引标记”的方法。填充完后,遍历辅助数组,找出第一个为0值的索引。想到了两种方法,一种时间复杂度较高,一种空间复杂度较高。
2025-04-18 19:35:27
763
原创 【Hot100】238. 除自身以外数组的乘积
你的代码思路是正确的,但存在一些边界条件处理的问题,特别是当数组长度为1或2时。我们可以优化这个解法,使其更加简洁且正确处理所有边界情况。这道题的要求是不能使用除法,如果可以使用除法将会简单很多。不使用除法还要在O(n)的时间复杂度写出来,没想到怎么解决。这种方法的时间复杂度为O(n),空间复杂度为O(1)(不包括输出数组),且正确处理了所有边界情况。看了下题解,是先遍历两次分别计算前缀乘积和后缀乘积,然后再让前缀与后缀相乘得到结果。
2025-04-17 10:52:26
835
原创 【Hot100】189. 轮转数组
你的方法二和方法三都是可行的思路,但确实存在一些效率或空间上的问题。让我来分析一下这两种方法,并给出更优的解法。方法三:首先记录下倒数k个元素值,然后从后往前移动数组移动k个位置。但是这样还是借用了O(k) 的空间。方法二:不适用O(n)的空间复杂度,原地移动nums。但是这个方法时间复杂度太高了,每次只移动一位。这些方法都比简单的逐位移动更高效,特别是当数组较大时。三次反转法实现简单且效率高,是推荐的解法。这道题说要使用三种方法,首先第一种最简单的就是使用额外的空间来进行。
2025-04-17 10:17:12
251
原创 【Hot100】56. 合并区间
更简洁,逻辑更清晰。避免了冗余的边界检查。更容易理解和维护。时间和空间复杂度与之前相同,但实际运行效率可能更高(因为减少了不必要的操作)。
2025-04-16 13:31:31
1010
原创 【Hot100】53. 最大子数组和
定义dp[i]为以nums[i]结尾的子数组的最大和。为什么这样定义?子问题划分如果我们能求出以每个nums[i]结尾的最大子数组和,那么全局最大子数组和一定是这些dp[i]中的最大值。这样定义可以确保我们覆盖所有可能的子数组(因为任何子数组都会以某个nums[i]结尾)。递推关系以nums[i]结尾的子数组只有两种可能:单独一个nums[i](即子数组长度为 1)。接在以nums[i-1]结尾的子数组后面(即子数组长度 > 1)。因此,dp[i]的值取决于nums[i]和的大小关系。
2025-04-16 11:13:41
1055
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人