自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(277)
  • 问答 (7)
  • 收藏
  • 关注

原创 leetcode hot100 394. 字符串解码 medium 栈 单栈模拟法

时间复杂度O(N):虽然有嵌套的 while,但每个字符最多进栈出栈两次。空间复杂度O(N):用于存储栈内的中间结果。N为解码后字符串长度。

2026-02-26 20:23:30 78

原创 leetcode hot100 155. 最小栈 medium

对于栈的所有操作,其时间复杂度都是 常数级 的。,当 push 一个元素时:栈顶 = 当前最小值。在“新来的数”和“旧的最小值”比较,只压入最小值。全部 O(1) 时间复杂度。

2026-02-26 19:53:06 299

原创 leetcode hot100 20. 有效的括号 easy 栈

空间复杂度:O(n):最坏情况下(比如全部是左括号 ((((((),需要把所有字符都存入栈中。时间复杂度O(n):只遍历了字符串一次,入栈和出栈的操作都是。

2026-02-26 19:29:37 43

原创 leetcode hot100 153. 寻找旋转排序数组中的最小值 medium 二分查找

由于 mid 是向下取整,mid == right 只会在 left == right 时发生。此时返回 ans 是正确的。的前提下,nums[mid] == nums[right] 只有一种情况会发生:就是 mid == right。(比如 LeetCode 154 题) return ans 就会提前收工,导致错误。🚩 潜在的问题:else: return ans。时返回mid坐标,找不到结束循环时,是。时,让循环继续,则结束循环时,是。

2026-02-25 18:31:37 269 1

原创 leetcode hot100 33. 搜索旋转排序数组 medium 二分查找

尽管逻辑多了一层判断,但依然每次排除了数组的一半。例如:[4,5,6,7,0,1,2]然后判断 target 在哪一侧。数组原本有序,但被旋转。只使用了常数个指针变量。

2026-02-25 11:24:40 62

原创 leetcode hot100 34. 在排序数组中查找元素的第一个和最后一个位置 二分查找 medium

在普通的二分查找中, 一旦 nums[mid] == target 就直接 return,这样只能找到“某一个 target”,ans 则为-1(找不到),或为最左、最右坐标。这题中,要修改为:返回值ans初始值 -1。两次完整的二分查找。这是一个 找左右边界 的问题。只用了几个指针变量。

2026-02-25 11:07:48 96

原创 leetcode hot100 74. 搜索二维矩阵 二分查找 medium

这意味着:整个矩阵如果按行“拉直”,是一个严格递增的一维数组。不需要真的展开数组,只需要“映射索引”。时间复杂度 O(log(mn))所以可以直接用 二分查找。空间复杂度:O(1)

2026-02-25 10:35:28 121

原创 leetcode hot100 35. 搜索插入位置 medium 二分查找

【代码】leetcode hot100 35. 搜索插入位置 medium 二分查找。

2026-02-24 20:58:42 81

原创 leetcode hot100 131. 分割回文串 medium 递归回溯

是指:从左往右读和从右往左读完全一样的字符串。

2026-02-24 20:34:55 181

原创 leetcode hot100 79. 单词搜索 medium 递归回溯

是 Python 集合的并集运算符,表示把 tmp 和 {(i,j)} 合并成一个新的集合。暂时把当前格子变成一个“不可能匹配任何字符”的值,防止下一层递归再次走回这个格子。那后面从别的起点开始搜索时,这个格子永远是 #,会破坏搜索。已经没有下一个字符需要匹配了,之前所有字符都匹配成功。因为一旦找到答案,搜索立刻终止,后续路径不再执行。为什么这样就不会超时?

2026-02-21 01:19:01 619

原创 leetcode hot100 22. 括号生成 medium 递归回溯

在每一层递归中,tmp + “(” 会创建一个新的字符串。由于是深度优先搜索(DFS),内存中在同一时刻只会存在从根节点到当前节点的一条路径上的字符串。每层 2 个分支 → 完全二叉树大小 = 2^(2n) = 4^n。总结:严格来说,时间复杂度是有效组合数乘以生成每个组合的代价。生成的序列数量:生成的所有合法括号组合的数量正是第。字符串操作开销:在每一条有效路径的末尾,执行了。但通常在面试中,回答其复杂度与卡特兰数成正比,较大时,根据斯特林公式近似,它的量级约为。递归栈深度 = 2n → O(n)

2026-02-20 23:48:37 361

原创 leetcode hot100 39. 组合总和 medium 递归回溯

在 Python 中,+ 拼接列表和 [:] 切片都会创建一个新列表,时间复杂度为。是所有可行解组合的总长度。在 LeetCode 的约束下,这通常是可接受的。这意味着每一轮递归都多出了一个。假设在递归的每一层都选择了数组中的最小值。分支因子 (Width),每一层最多有。每层会创建新的切片列表:最长为。新的 tmp 路径列表:最长为。

2026-02-20 23:30:57 315

原创 leetcode hot100 17. 电话号码的字母组合 medium 递归回溯

每一层选择“当前数字”对应的一个字母。

2026-02-20 21:18:39 75

原创 leetcode hot100 78. 子集 递归回溯 medium 位运算法

选 或 不选。

2026-02-20 21:06:31 143

原创 leetcode hot100 46. 全排列 medium 递归回溯 dfs

在 Python 中,path 是一个列表对象(引用)。如果不使用切片 [:] 拷贝一份副本,最终 res 里的所有元素都会指向同一个被清空的 path 对象。回溯的核心在于:尝试选择 -> 递归进入下一层 -> 撤销选择(回退)。,且需要 used 数组和 path 数组。的时间复制到结果集中。

2026-02-20 20:04:41 130

原创 leetcode hot100 208. 实现 Trie (前缀树) medium 从二叉树到二十六叉树

当我们要存储 “cat” 和 “car” 这两个单词时,它们都以 “ca” 开头。Trie 会把公共前缀 “c” 和 “a” 共享,然后从 ‘a’ 节点分叉,一个指向 ‘t’,一个指向 ‘r’。这样不仅节省了存储空间,查询时也只需要沿着路径走一遍。Trie,也叫前缀树或字典树,是一种专门用来高效处理字符串的数据结构。假设在 Trie 中只插入了一个单词:apple。

2026-02-17 01:12:06 60

原创 leetcode hot100 207. 课程表 检测有向图中是否存在环 medium Kahn 算法 入度表 BFS 图论

如果有环(比如 A 依赖 B,B 依赖 C,C 又依赖 A),无法毕业。如果在递归过程中,发现下一个节点在递归栈中(正在访问中),则找到了环。是先修关系的数量(prerequisites 的长度)。这个图是不是一个有向无环图(DAG)?是课程总数(numCourses),例如: 修完B可以修[A,C],,把题目全部放入队列。

2026-02-16 19:33:58 373

原创 leetcode hot100 994. 腐烂的橘子 medium bfs

DFS 是一条路走到黑。而这道题要求的是**“最小分钟数”,这本质上是在求最短路径/层数**,是 BFS。时间复杂度:O(mn),其中 m 和 n 分别为 grid 的行数和列数。先把网格里所有腐烂的橘子坐标都放进一个。这就是“层序遍历”:每一分钟就是 BFS 的一层。空间复杂度:O(mn)。

2026-02-16 17:46:36 104

原创 leetcode hot100 200. 岛屿数量 medium dfs

DFS 过程:虽然每个 ‘1’ 都会触发 DFS,注意:每个格子最多只会被访问两次(一次是在双重循环扫描时,另一次是在 DFS 感染时被标记为 ‘0’)。一旦格子被标记为 ‘0’,它就再也不会进入 DFS 的逻辑。空间开销主要来自递归调用的系统栈高度。最坏情况:如果整个网格全是陆地(全为 ‘1’),DFS 会从一个点开始感染。在递归过程中,由于是深度优先,系统栈的深度可能会达到整个网格的大小。遍历过程:需要使用双重循环遍历整个网格的每一个格子,这部分是。,这样最后统计出来的不是“岛屿的数量”,而是。

2026-02-16 16:45:02 99

原创 递归回溯本质

(左边汇报是对称的)

2026-02-16 00:00:23 75

原创 leetcode ho100 124. 二叉树中的最大路径和 hard

空间复杂度:O(n)。最坏情况下,二叉树退化成一条链,递归需要 O(n) 的栈空间。时间复杂度:O(n),其中 n 为二叉树的节点个数。

2026-02-15 23:51:07 78

原创 leetcode hot100 236.二叉树的最近公共祖先 medium dfs 递归

不存在,或者它们是树中最深的叶子节点),我们需要遍历二叉树中的每一个节点。每个节点只会被访问一次。在每个节点上,我们只进行了常数时间的逻辑判断(判断是否等于。在 DFS 回溯的过程中,每个节点都向它的父节点汇报情况:“我这棵子树里有没有发现。最好情况:当二叉树是完全平衡的,树的高度。最坏情况:当二叉树退化成一个链表(高度。此时递归深度最小,空间复杂度为。,以及合并左右子树的汇报结果)。在最坏的情况下(比如目标节点。)时,递归的深度会达到。

2026-02-15 23:23:05 104

原创 leetcode hot100 437. 路径总和 III medium 前缀和 DFS

哈希表记录:使用一个哈希表,存储当前路径上所有出现过的前缀和,及其出现的次数。如果树中全是正数,前缀和是严格递增的,确实不会重复。所以需要一个哈希表,记录:当前路径上所有出现过的前缀和,及其出现的次数。,哈希表在最坏情况下(树呈链状)需要存储。问题转换为:检查当前节点。,每个节点仅遍历一次。

2026-02-15 22:55:01 275

原创 leetcode hot100 105. 从前序与中序遍历序列构造二叉树 medium 前序遍历 中序遍历

输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7] 输出: [3,9,20,null,null,15,7]不用传入preorder、inorder、my_dict。my_dict,每次查找根节点只需要。,递归栈最坏情况下占用。直接调用:build。

2026-02-11 20:35:14 277

原创 leetcode hot100 114. 二叉树展开为链表 先序遍历 链表 medium

空间复杂度:O(N):如果这棵树已经退化成了一个链表(瘦长型),递归深度就是。每一层递归都会在内存里开辟一个小房间,这就导致了。然后递归,从当前节点的右节点(2)开始。这是从上到下创建链表的。时间复杂度:O(N)

2026-02-11 19:36:24 37

原创 leetcode hot100 199. 二叉树的右视图 medium 层序遍历dfs

W 是树的最大宽度(即节点最多的一层)。在满二叉树中,最后一层大约有 N/2 个节点,所以空间复杂度最坏也是 O(N)。虽然我们只取每层第一个看到的,但为了确认没有更深的节点,程序必须遍历完整棵树。我们必须访问树中的每一个节点(每个节点进出队列各一次),N 为节点总数。一层一层地遍历树,只记录每一层的最后一个节点。H 是树的最大高度。这是由递归产生的系统栈深度决定的。,此时 DFS 比 BFS 节省很多内存。递归的同时记录深度,根-右-左。工具:队列(Queue)。,此时两者空间开销差不多。

2026-02-09 20:40:43 123

原创 leetcode hot100 230. 二叉搜索树中第 K 小的元素 medium

空间复杂度:O(h),其中 h 是二叉树的高度。递归需要 O(h) 的栈空间。最坏情况下,二叉树退化成一条链,递归需要 O(n) 的栈空间。滚向 4 的右子树,先钻到该子树的最左边,碰到 5,点名(时间复杂度:O(n),其中 n 是二叉树的节点个数。二叉搜索树中,最小的元素在最左边的深处。深入最左:球必须先滚到最左边的 1。二叉搜索树的中序遍历为递增序列。滚向 2 的右边碰到 3,点名(”的过程中,才真正开始了“回弹点名:碰到 1,点名(大回弹到 4,点名(

2026-02-09 20:13:22 98

原创 leetcode hot100 98. 验证二叉搜索树 medium 递归

怎么判断一个数组是有序数组?比较相邻元素的大小即可。取决于树的高度,也就是递归栈的深度。

2026-02-09 14:38:05 63

原创 leetcode hot100 108. 将有序数组转换为二叉搜索树 medium 递归

如果 n 是偶数,我们可以取数组正中间左边那个数作为根节点的值,也可以取数组正中间右边那个数作为根节点的值。下面代码取的是正中间右边那个数,即下标为 n/2的数(当 n 是偶数时)。有序数组就像是 BST 的中序遍历结果。要把一个有序数组变成一棵平衡的 BST,最简单的方法就是:永远挑数组的正中间作为根节点。二分查找是在有序数组里“找”一个数,而这道题是把二分查找的每一个“中点”连起来变成了一棵树。我们需要把数组里的每个数都“摸”一遍,把它们变成节点。如果数组是乱序的,必须先给它排序(

2026-02-09 10:43:03 604

原创 leetcode hot100 102. 二叉树的层序遍历 medium BFS

如果处理这一层节点的同时又往队尾加人(下一层节点),不数一下的话,就会一直处理下去,分不清谁是谁家的孩子。在最坏情况下(树是满二叉树),队列中最多会存储。个节点(即最底层节点的数量)。每个节点入队一次,出队一次。

2026-02-06 11:29:01 67

原创 leetcode hot100 543. 二叉树的直径 easy 递归

对于节点 B:它是叶子,depth(B.left) 和 depth(B.right) 都是 0。我们需要一个全局变量 self.ans(直径),在递归计算每个节点的高度时,顺便更新 self.ans 的最大值。要算的是直径(路径长度),但递归最擅长算的是高度。在 Python 中,如果你在函数内部直接写 ans = 0,它会被当作一个局部变量。此时,经过 A 的路径就是 B -> A -> C。在二叉树中,直径的定义是路径上的“边”的数量。:取决于递归栈的深度(树的高度),最坏情况。

2026-02-06 10:24:37 279

原创 leetcode hot100 easy 101. 对称二叉树 递归 层序遍历 bfs

BFS 的标准实现就是利用循环(while)和队列(Queue)进行的迭代。判断一棵树是否对称,本质上是看它的左子树和右子树是否互为“镜像”。辅助函数:任务是“检查这两个节点是不是镜像的”。原函数:任务是“检查这棵树是不是对称的”。层序遍历(BFS)本质上就是迭代。,最坏情况下队列会存储大量节点。每个节点最多被访问一次。每个节点最多被访问一次。

2026-01-31 22:01:51 371

原创 leetcode hot100 226. 翻转二叉树 easy 递归 层序遍历 BFS

中序遍历的要求是“左-根-右”。因为在算出左边多高、右边多高之前,没法操作。这属于后序位置的操作。只有拿到了子问题的答案,当前层的逻辑才能运行。既然是“每一个节点都要交换左右孩子”,我们也可以像剥洋葱一样,一层一层地处理。在中序遍历里,操作是 res.append(node.val)。在最大深度里,操作是 max(left, right) + 1。递归:对左儿子进行同样的翻转,对右儿子也进行同样的翻转。翻转操作不需要知道子树的情况。交换:把当前节点的左儿子和右儿子互换位置。

2026-01-31 21:41:36 285

原创 leetcode hot100 104. 二叉树的最大深度 easy 递归dfs 层序遍历bfs

(根节点自己) + 左右子树深度中的最大值。取决于树最宽的那一层节点数。剥洋葱:剥掉一层,计数器加。一棵树的最大深度 =每个节点都要问一遍。每个节点都要问一遍。可以直接用原函数递归。

2026-01-31 21:18:09 136

原创 leetcode hot100 94. 二叉树的中序遍历 easy 递归 dfs

程序是一直钻到最深的左节点,然后才开始收集第一个数字。这给人一种“从最底层开始处理”的感觉。在最坏情况下(树呈链状),递归深度或栈的高度会达到。既然是“左-根-右”,就按照这个顺序调用函数即可。每个节点都会被访问且仅被访问一次。这意味着对于每一棵子树,

2026-01-31 20:44:08 87

原创 leetcode hot100 146. LRU 缓存 medium OrderedDict 双向链表 双向字典 哈希表

(Least Recently Used)是最经典的内存淘汰策略,其设计原则是“如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小”。即根据数据的最近访问时间来进行淘汰,缺点是可能会由于一次冷数据的批量查询而误删除大量的热点数据。(First In First Out)先进先出策略会将数据按照写入缓存的顺序进行排队,当缓存空间不足时,最先进入缓存的数据会被优先删除。是一种比较死板的策略不考虑数据热度可能会淘汰大量的热点数据,但是实现起来相对容易。随机淘汰策略,一般不建议使用。

2026-01-31 20:32:18 742

原创 leetcode hot100 23. 合并 K 个升序链表 hard 分治 迭代

把 lists[0] 和 lists[4] 合并(相当于合并前八条链表),合并后的链表保存在 lists[0] 中;:把 lists[0] 和 lists[2] 合并(相当于合并前四条链表),合并后的链表保存在 lists[0] 中;把 lists[4] 和 lists[6] 合并,合并后的链表保存在 lists[4] 中;:把 lists[0] 和 lists[1] 合并,合并后的链表保存在 lists[0] 中;lists[3] 合并,合并后的链表保存在 lists[2] 中;这是此解法的核心优势。

2026-01-31 19:47:12 651

原创 leetcode hot100 148.排序链表 medium 递归 分治 | 冒泡排序

2:Level 2 (右): 同样的过程,sortList([1,3]) 拆分后合并,返回 [1,3]。3: Level 3 (触底): sortList([4]) 和 sortList([2]) 启动。动作:在内存里新开辟了一块空间,创建了一个全新的盒子,并把 l1.val 复印了一份放进去。动作:把 dummy.next 这根“指针线”指向了已经存在的 l1 节点。2: Level 2 (左): sortList([4,2]) 启动。1: sortList([4,2,1,3]) 启动。

2026-01-30 19:50:51 342

原创 leetcode hot100 138. 随机链表的复制 medium

但这道题多了一个 random 指针,它可能指向链表中的任何一个节点(可以是它自己,或者它前面的节点)。普通的链表拷贝只需要处理 next 指针,顺着头往后走就行了。原链表每个节点有两个指针,next 和 random。复制的节点建立 next 和 random 后。拆分长链表时,用next重组旧链表和新链表。

2026-01-30 17:35:19 115

原创 leetcode hot100 25. K 个一组翻转链表 hard

虽然有嵌套循环,但每个节点实际上只被访问了常数次(一次是定位 tail,一次是翻转)。只额外使用了常数个指针,属于原地翻转。

2026-01-29 14:51:41 197

空空如也

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

TA关注的人

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