- 博客(135)
- 收藏
- 关注
原创 53.全排列组合
本文介绍了一种使用回溯算法解决全排列问题的方法。通过递归和状态回退,生成输入数组所有可能的排列组合。算法核心是维护一个访问标记数组和当前路径,当路径长度等于输入数组大小时记录结果。每次递归尝试选择未被访问的元素,并在回溯时撤销选择,确保所有排列都能被探索。时间复杂度为O(n!),空间复杂度为O(n)。代码清晰展示了递归调用和状态回退的过程,适合用于理解回溯算法的经典实现。
2026-02-03 00:52:33
237
原创 51.课程表(拓扑排序)-leetcode207
本文解决课程选修顺序问题,通过拓扑排序判断是否存在可行的学习路径。算法使用邻接表存储课程依赖关系,维护入度数组记录每门课程的先修要求。初始化时将入度为0的课程入队,依次处理队列中的课程,将其后修课程的入度减1,若减至0则入队。最终比较已学课程数与总课程数,若相等则返回true,否则返回false。该算法能有效检测课程依赖中是否存在循环依赖,确保学习顺序的可行性。
2026-02-01 21:23:39
263
原创 50.腐烂的橘子
在给定的m x n网格grid012每分钟,腐烂的橘子的新鲜橘子都会腐烂。返回直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回-1。
2026-01-31 21:27:50
76
原创 49.二叉树的最大路径和
借鉴了评论区的哥们ID:烟雨入江南这道题说难也不难,但说容易也真不是那么容易能想到的(写得比较多,但都是心得,耐心看完就更上一层楼了)。首先就是递归的方式,很多人都对递归一头雾水,一看就会,一写就废。不用担心,这是正常现象。下面,我们详细解释一下这道题,顺便疏通一下递归的基本思路。我们不要先去考虑整个递归的代码怎么去写,而是要明确一个递归的主体,就是这个递归的主体要怎么构造,然后再去想边界条件,返回值等等。
2026-01-29 17:09:16
379
原创 48.节点最近公共祖先
对左子树递归,找q或者p节点,找到了就返回对右子树递归,找q或者p节点,找到了就返回把递归的代码返回值当作已经处理完后,不要陷入递归函数里面去,要什么递归函数就返回了什么。
2026-01-29 15:18:33
101
原创 45.二叉树前序遍历展开为链表
递归:先递归前序遍历二叉树,把节点存入vector,然后遍历vector逐步调节指针迭代:基于前序遍历的非递归算法,借助一个栈,边遍历边调节指针,本题代码给出非递归算法。
2026-01-28 09:41:52
112
原创 40.二叉树的层序遍历
本文实现了一个二叉树的层序遍历算法。通过队列结构,逐层处理节点:1)初始化时将根节点入队;2)使用cur_lever_size记录当前层节点数;3)内循环处理当前层所有节点,将其值存入临时数组,同时统计下一层节点数next_lever_size;4)完成当前层处理后更新层节点数并保存结果。相比直接调用q.size(),该方法通过显式记录每层节点数使流程更清晰。时间复杂度O(n),空间复杂度O(n),能有效处理空树情况,返回按层组织的二维数组。
2026-01-26 16:00:50
199
原创 39.二叉树的直径
本文介绍求二叉树直径(最远两节点距离)的算法。采用深度优先搜索遍历二叉树,在计算节点深度的同时维护最大直径值。关键点在于:每个节点的直径等于左右子树深度之和,全局变量ans记录遍历过程中的最大值。时间复杂度O(n),空间复杂度O(h),其中n为节点数,h为树高。该解法巧妙地将最大深度计算与直径求解结合,通过后序遍历实现高效计算。
2026-01-25 21:03:18
181
原创 39.判断对称二叉树
本文介绍了两种判断二叉树是否对称的方法:1.迭代法使用队列层序遍历,每次取出两个节点比较,按照左左、右右、左右、右左的顺序入队。若节点值不匹配或结构不对称则返回false,否则继续遍历直至队列为空。2.递归法定义辅助函数处理左右子树,递归比较左子树的左节点与右子树的右节点,以及左子树的右节点与右子树的左节点。两种方法都通过比较节点值和结构对称性来判断二叉树是否对称。
2026-01-24 22:08:13
176
原创 38.交换二叉树中所有的左右节点
摘要:本文讨论了二叉树翻转的递归解法,强调理解递归时要抓住base case(如空节点)和递归出口,避免陷入多层递归细节。通过图解展示了交换左右子树的过程,并给出了简洁的C++实现代码:先递归处理左右子树,再交换当前节点的左右指针,最后返回根节点。关键在于从基础情况出发,避免过度追踪递归层级。
2026-01-24 21:15:00
273
原创 35.LRU缓存(最久未访问)问题
本文实现了一个LRU缓存算法,使用循环双链表和哈希表结合的方式。链表头部存放最近访问的节点,尾部是最久未访问的节点。当缓存满时自动删除尾部节点。主要操作包括:get()获取键值并将节点移至头部;put()插入新节点或更新已有节点,若容量超限则删除尾部节点。通过哈希表快速定位节点,链表维护访问顺序,实现O(1)时间复杂度的存取操作。关键方法包括节点删除、头部插入和哈希表维护,确保LRU策略高效执行。
2026-01-23 21:51:23
197
原创 22.找到两个链表相交的节点
【摘要】该代码实现了查找两个单链表相交节点的功能。主要思路是:先分别计算两个链表的长度,然后将较长链表的指针向后移动长度差值步,使两个指针处于相同起始位置。最后同时遍历两个链表,当找到相同节点时即为相交节点。时间复杂度为O(m+n),空间复杂度为O(1)。关键步骤包括:1)计算链表长度;2)对齐起始位置;3)同步遍历查找交点。若链表不相交则返回NULL。
2026-01-21 19:43:28
193
原创 21.在有序的二位数组中用O(m+n)的算法找target
摘要:本文提出了一种在二维矩阵中搜索目标值的算法。算法首先遍历第一行找到第一个大于目标值的位置,然后从该位置开始向下搜索。当遇到大于目标值的元素时回退列继续搜索,直到找到目标值或遍历完矩阵。代码实现采用双指针方法,时间复杂度优化为O(m+n),适用于有序矩阵的高效搜索。
2026-01-20 20:38:12
142
原创 20.右旋转图片
本文介绍了一种旋转二维矩阵的方法。解题思路分为两步:首先沿主对角线转置矩阵(仅遍历上三角区域),然后逐行进行逆序操作。代码实现中,先通过双重循环完成转置,再对每行使用双指针法进行逆置。这种方法通过两次线性变换实现了矩阵的90度旋转,时间复杂度为O(n²)。关键点在于理解转置和逆序操作的组合效果,建议通过画图辅助理解该算法的实现过程。
2026-01-20 19:35:33
192
原创 19.旋转输出矩阵
摘要:本文实现了一个螺旋顺序遍历二维矩阵的算法。通过设置上下左右四个边界,依次顺时针遍历矩阵外层,每次遍历后收缩相应边界,直到遍历完所有元素。算法处理了空矩阵等边界情况,使用动态分配数组存储结果,时间复杂度为O(mn)。代码中通过四个方向的循环遍历和边界判断,确保正确生成螺旋顺序的输出数组。
2026-01-19 20:05:44
166
原创 18.矩阵同行同列全置零
摘要:本文讨论了矩阵置零问题的两种解法。第一种边遍历边置零的方法存在缺陷,会导致后续遍历时误判已置零元素。第二种改进方案采用标记法:先遍历矩阵记录需要置零的行列,然后统一置零。该方法通过两个辅助数组tag_row和tag_col记录标记,最后根据标记批量处理,避免了第一种方法的错误。空间复杂度为O(m+n),但保证了算法的正确性。
2026-01-19 12:33:41
217
1
原创 16.求数组除了当前元素的所有乘积
摘要:本文提出了两种计算数组中除自身外元素乘积的算法。第一种思路先计算所有元素的乘积,再通过除法得到结果,但需要单独处理0的情况。第二种更优的思路避免了除法运算,通过两次遍历分别计算每个元素左边和右边的乘积,最后合并得到结果。代码实现了第二种方法,使用left和right数组存储左右乘积,最终相乘得到结果数组res。该方法时间复杂度为O(n),空间复杂度为O(n)。
2026-01-18 19:54:04
185
原创 15 .数组右移动k个单位
摘要:该算法实现了数组的向右轮转操作。通过使用临时数组保存后k个元素,将原数组前部元素后移k位,再将临时数组元素复制到数组前部。处理了k大于数组长度的情况(取模运算)和边界条件。示例展示了输入[1,2,3,4,5,6,7]经3次轮转后变为[5,6,7,1,2,3,4]的过程。
2026-01-18 19:19:32
195
原创 14.合并区间(1,3)(2,5)=(1,5)
本文介绍了合并重叠区间的算法。首先对区间按左边界排序,然后遍历每个区间,与前一个区间比较:若当前区间左边界不大于前一区间的右边界则合并,取两者的最大右边界作为新区间的右边界;否则直接加入结果集。代码实现展示了这一过程,通过排序和逐个比较合并的方式高效解决问题。示例展示了不同情况下的合并结果。
2026-01-17 19:05:05
220
原创 13.找到连续数组的最大和
摘要:本文探讨了求解最大子数组和问题的两种方法。暴力解法通过双重循环枚举所有子数组,时间复杂度O(n²)。更优的动态规划解法定义dp[i]为以nums[i]结尾的最大子数组和,通过状态转移方程dp[i] = max(dp[i-1]+nums[i], nums[i])进行计算,最终在dp数组中取最大值。两种方法均给出实现代码,动态规划解法将时间复杂度优化至O(n)。
2026-01-17 17:59:19
376
原创 10.和为k的连续元素子数组个数
摘要:该算法统计整数数组中连续子数组和等于k的个数。采用双重循环枚举所有可能的子数组,外层循环固定起点i,内层循环计算从i开始的连续元素和。当和等于k时计数器加1,大于k时提前终止当前循环。时间复杂度为O(n²),空间复杂度O(1)。示例输入nums=[1,1,1],k=2时输出2,nums=[1,2,3],k=3时输出2。
2026-01-16 15:17:57
165
原创 T8-T9滑动窗口总结
k++){//找在[i,j-1]内,有没有s[m]==s[j]的元素,如果有则移动左窗口缩减窗口大小。//j是窗口右侧,i是窗口左侧。// 对窗口子串排序(左闭右开,范围是[0, wnd_size))//移动到重复元素的右边一个元素。while(j<wnd_size){//对比字符是否完全一致。while(j<s.size()){//遍历到最后一个元素。// 截取当前窗口的子串(避免修改原s)T8是可变的滑动窗口,T9是固定大小的滑动窗口。
2026-01-09 01:02:29
236
原创 9.找到字符串中所有字母异位词
题目要求找出字符串s中所有与字符串p构成异位词的子串起始索引。解题思路是将p排序后,在s中滑动固定大小的窗口(窗口大小为p的长度),每次将窗口内子串排序后与p比较。若匹配则记录起始索引。虽然该方法时间复杂度较高(O(n^2)),但思路直观易懂。示例展示了"cbaebabacd"中"abc"的异位词出现在索引0和6处。代码通过substr截取窗口子串并排序,与排序后的p逐个字符比较来实现匹配检测。
2026-01-09 00:59:01
153
原创 8.最长的无重复字符的子串
摘要:本文介绍了一种寻找字符串中最长无重复字符子串的滑动窗口算法。使用双指针i和j表示窗口边界,j遍历字符串时检查[i,j-1]范围内是否存在重复字符,若有则移动i调整窗口。通过比较j-i+1与当前最大值来更新结果。该算法时间复杂度为O(n²),空间复杂度O(1),能有效解决此类问题。
2026-01-08 23:04:04
207
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅