自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 LC.102 | 二叉树的层序遍历 | 树 | BFS(队列遍历)

依次将当前层节点弹出、存进结果,再把下一层节点推入队列。要求:返回从上到下、从左到右的层序遍历结果。本层的大小由队列当前 size 决定。时间复杂度:O(n)空间复杂度:O(n)层序遍历思路非常固定。

2025-11-24 15:28:59 125

原创 从 sort 到 priority_queue:C++ 标准对 Lambda 支持的完整演进

在刷 LeetCode 时,遇到一个问题,我想用 Lambda 表达式自定义排序。用在 std::sort 上,一行代码搞定,丝滑流畅;用在 std::priority_queue 上,直接报错,查了查,学着用 decltype(cmp) 解决问题。为什么会有这种巨大的差异?带着这个疑问,本文将深入底层,彻底揭开sort、Lambda 与decltype之间错综复杂的“猫腻”。特性 / 版本C++98/03C++11C++17自定义排序工具struct仿函数Lambda表达式Lambda。

2025-11-24 14:09:47 951

原创 基于范围的 for 循环 (Range-based for) 原理与实践

只读遍历 (Read-only)首选零拷贝,高性能,且防止误修改。需要修改元素 (Write/Modify)首选理由:通过引用直接操作原数据。基础类型简单遍历对于intcharbool等微小类型,写在性能上无明显差异,但在模板编程或泛型代码中,依然建议保持的习惯。特定限制需要下标 -> 用...)需要删改容器结构 -> 用。

2025-11-24 11:14:37 662

原创 std::pair 使用指南

std::pair 是 C++ 标准库里最简单、出镜率又极高的“小工具类型”之一。不仅是“存两个数”的结构体,也常联动STL 各大容器使用,也是算法中状态记录的神器。本文旨在梳理 std::pair 的基础用法,并重点剖析它和 map / vector / stack / queue / priority_queue 等容器之间的深度联动。

2025-11-24 10:39:55 810

原创 LC.2331 | 计算布尔二叉树的值 | 树 | 递归遍历

时间复杂度:O(n)空间复杂度:O(h)要求:返回整棵树的布尔运算结果。输出:true / false。如果是叶子节点,直接返回。输入:一棵“布尔二叉树”先算出左右子树的布尔值。

2025-11-24 09:40:34 64

原创 LC.563 | 二叉树的坡度 | 树 | 递归遍历(子树和 + 全局累加)

整棵树的坡度 = 所有节点的坡度之和。时间复杂度:O(n)空间复杂度:O(h)要求:返回整棵树的总坡度。

2025-11-21 23:17:20 174

原创 LC.543 | 二叉树的直径 | 树 | DFS(深度 + 全局最长路径)

思路:实际上是每个节点都有一个左右子树深度,左树深+右树深最长的那个,就是题目要求的最长直径。可以先去做另外一题,求树的长度,再来做这题,思路就更清晰了。要求:返回二叉树的直径(任意两个节点之间的最长路径长度)输出:一个整数,表示最长路径的“边数”时间复杂度:O(n)空间复杂度:O(h)

2025-11-21 23:15:23 204

原创 LC.572 | 另一棵树的子树 | 树 | 递归遍历

时间复杂度:O(n × m) n 为 root 的节点数,m 为 subRoot 节点数。的根值相同,就可能成为子树的入口。空间复杂度:O(h)输出:true / false。

2025-11-21 23:11:54 176

原创 LC.100 | 相同的树 | 树 | 递归遍历

要求:判断两棵树是否结构相同且节点值全部相同。时间复杂度:O(n)空间复杂度:O(h)输出:true / false。一个空一个非空 → 不相同。输入:两棵二叉树 p、q。对应位置的节点值必须相同。树的结构必须完全一致。两者都为空 → 相同。

2025-11-21 17:26:17 110

原创 LC.965 | 单值二叉树 | 树 | 遍历

思路:核心判断条件非常简单:整棵树所有节点的值必须与根节点相同。遍历的时候顺手判定下就好。空间复杂度:O(h)时间复杂度:O(n)要求:判断所有节点的值是否都相同。输出:true / false。

2025-11-21 17:22:12 117

原创 LC.145 | 二叉树的后序遍历 | 树 | 递归遍历

时间复杂度:O(n)空间复杂度:O(n)输入:给定二叉树根节点。把当前节点的值加入结果。

2025-11-20 20:26:45 205

原创 LC.94 | 二叉树的中序遍历 | 树 | 递归遍历

然后访问当前节点(root->val)时间复杂度:O(n)空间复杂度:O(n)输出:vector<int>

2025-11-20 20:22:32 174

原创 LC.144 | 二叉树的前序遍历 | 树 | 递归遍历

使用递归方式实现,代码简洁清晰,是最标准的前序模板。遍历右子树(root->right)时间复杂度:O(n)空间复杂度:O(n)遍历左子树(root->left)输出:vector<int>输入:一棵二叉树的根节点。访问当前节点(root)

2025-11-20 20:20:43 142

原创 LC.49 | 字母异位词分组 | 哈希 | 构建相同的key

思路:核心思路自然是为每个字符串构造一个相同的 key,再把 key 相同的字符串放到同一个 vector 里。要求:将其中的字母异位词分组,返回每一组。字母异位词:两个字符串字符相同,但排列顺序不同。n = 字符串数量 m = 字符串最大长度。输出:vector<vector<string>>因此,用各字符的计数数组作为 key 非常自然。作为 key,这让整个分组过程变得非常直接。时间复杂度:O(n * m)空间复杂度:O(n * m)

2025-11-20 20:16:22 186

原创 LC.219 | 存在重复元素 II | 哈希 | 简单题

思路:和“存在重复元素”类似,但这题不止要判断是否重复,还需要判断重复的两个下标之间的距离是否 ≤ k。时间复杂度:O(n)空间复杂度:O(n)判断数组中是否存在两个不同下标。不满足 → 返回 false。因此,用哈希表记录某个数字。满足 → 返回 true。

2025-11-20 17:23:39 120

原创 LC.1 | 两数之和 | 哈希 | 简单题

并返回这两个数的下标(不能重复使用同一个元素)思路:把需要的结果和本身都存入哈希表。因为每个数只会扫一遍,所以速度非常快。输出:一个长度为 2 的数组,例如。时间复杂度:O(n)空间复杂度:O(n)要求:找到两个数,使它们的和等于。检查补数是否已经在哈希表中出现过。如果没出现,则把当前数字存进哈希表。如果出现过,找到答案,直接返回。

2025-11-19 11:14:58 166

原创 LC.205 | 同构字符串 | 哈希 | 元素映射

因此,我们只需要用两个 256 长度的数组(ASCII)记录它们各自“上一次出现的位置”。要求两个字符串同构,其实我们不需要关心具体的映射规则是什么;如果两个字符的上一次出现位置总是一致的,那么这个映射关系就是成立的。我们不关心 a1 映射成哪个字符,也不关心 a2 是哪个字符,中的某个字符(并且映射顺序不变),则两个字符串同构。思路:说是简单题,但是感觉也没有那么简单。空间复杂度:O(1)要求:判断它们是否是“同构”的。中出现的位置规律,必须与。中的每个字符,都可以。中出现的位置规律一样。

2025-11-19 11:11:45 137

原创 LC.242 | 有效的字母异位词 | 哈希 | 简单题

思路:既然都是小写字母,那么只需要一个长度为 26 的计数数组。的字母异位词(即两个字符串的字符种类和数量必须完全一致)最后如果所有计数都回到 0,说明两个字符串完全一致。在 s 中出现就 +1,在 t 中出现就 -1。时间复杂度:O(n)空间复杂度:O(1)输出:true / false。

2025-11-19 10:57:13 172

原创 LC.347 | 前 K 个高频元素 | 哈希| 小顶堆

用哈希表统计每个数字的出现次数,然后用一个“小顶堆”维持频次前 k 高的数字。,堆顶永远是当前最小频次的那个,一旦堆超过 k 就弹掉堆顶。时间复杂度:O(n log k)空间复杂度:O(n)要求:返回数组中出现频率最高的。思路:核心思路是数据结构的运用。输出:长度为 k 的数组。

2025-11-19 09:55:54 131

原创 LC.383 | 赎金信 | 哈希 | 简单题

空间复杂度:O(1) (字符只有26个 哈希表是常数级)时间复杂度:O(n + m)中的字符只能被使用一次,判断是否能构成。输出:true/false。

2025-11-19 09:51:50 92

原创 LC.1460 | 通过翻转子数组使两个数组相等 | 哈希 | 简单题

思路:子数组翻转的本质是「任意重排」。因为连续片段随便反转,等价于可以把数组排序成任意顺序。时间复杂度:O(n)空间复杂度:O(n)输出:true / false。所以最终只需要判断两个数组的。输入:两个长度相同的数组。

2025-11-18 16:56:32 180

原创 LC.350 | 两个数组的交集 II | 哈希 | 简单题

中每个数字的出现次数,再对照取每个数字出现次数的。时间复杂度:O(n + m)空间复杂度:O(n + m)等于它在两个数组中出现次数的。思路:用两个哈希表分别统计。每个元素在结果中出现的次数。,把它加入结果即可。

2025-11-18 16:54:36 200

原创 LC.1436 | 旅行终点站 | 哈希 | 简单题

思路:用一个哈希表记录所有出现过的“起点”,然后再找那个从来没有作为起点出现过的城市,它就是终点站。时间复杂度:O(n)空间复杂度:O(n),表示从城市 A → 城市 B。输出:终点城市的名称。

2025-11-18 16:51:56 115

原创 LC.41 | 缺失的第一个正数 | 哈希 | O(n)

思路:这一道困难题,感觉真有点脑筋急转弯的风味,核心在于要明白答案只会出现在[1,n+1]中,就是无论怎么折腾,最终的答案一定会出现在这个范围内,想明白这一点,做起来就很方便了。即值为 n 的数字,应该放在下标 n-1 的位置。如果一堆数字都不在正确的位置上,那也没关系,我们找到第一个不在的,它就是答案。如果所有 1~n 都在正确的位置上,那么答案就是 n+1。空间复杂度:O(1)(可以修改原数组)时间复杂度:O(n)空间复杂度:O(1)输入:一个未排序整数数组。时间复杂度:O(n)

2025-11-18 16:48:32 178

原创 LC.128 | 最长连续序列 | 哈希 | 左右扩散查找

从每个数字开始,向左、向右扩散查找,把能扩下去的全部取完,并把访问过的数字标记为 0,避免重复计算。时间复杂度:O(n) 每个数字最多被访问一次。空间复杂度:O(n) 哈希表存储所有数字。不要求序列在原数组中连续。输入:一个未排序整数数组。输出:最长连续序列的长度。

2025-11-18 16:36:17 107

原创 LC.217 | 存在重复元素 | 哈希 | 哈希查找

输出:存在重复 → 返回 true 否则 → 返回 false。时间复杂度:O(n)空间复杂度:O(n)要求:判断数组中是否存在。

2025-11-17 10:43:14 157

原创 LC.202 | 快乐数 | 哈希 | 模拟

这一题的核心在于快乐数要么true,要么进入死循环,进入死循环的意思就是会重复变成出现过的数字,进而判定为false。,大概是十位左右的数字。思路:直接模拟 + 用哈希表记录出现过的中间值,用来判断是否进入死循环。即便 n 是 2³¹ - 1 这种十位数,一次迭代后最大也就跌到。而像 243 等值继续平方和,又会迅速跌到几十甚至更小的数字。因此所有 < 1000 的数,下一步一定 ≤ 243。最终,不论初始 n 是多少,它都会被压缩进一个。空间复杂度:O(log n)一旦重复,就形成环,也就是我们所说的。

2025-11-17 10:40:52 261

原创 LC.706 | 设计哈希映射 | 哈希 | 模拟

时间复杂度:put:O(n) get:O(n) remove:O(n)如果存在 → 再遍历 tmp,把对应 key 的 value 改掉。思路:和 LC.705(哈希集合)一样,我继续偷懒,用;空间复杂度:O(n)判断 key 是否存在。如果不存在 → 直接。

2025-11-17 10:28:30 126

原创 LC.705 | 设计哈希集合 | 哈希 | 模拟

时间复杂度:add O(1) remove O(n) contains O(n)思路:偷懒了,用一个vector<int>当做容器处理。虽然用vector慢归慢,但是功能是都实现了(bushi。要求:实现add、remove、contains函数。remove:遍历vector,找到就置为-1。空间复杂度:O(n)add:直接push_back。contains:遍历查找。

2025-11-17 10:25:10 141

原创 LCR.184 | 设计自助结算系统 | 队列 | 队列/双端队列

要求:按要求实现get_max()、add(value)、remove()三个函数。如果移除的元素刚好等于 qmax 的队头,qmax 也要同步弹掉队头。思路:普通队列搭配双端队列使用,维护一个单调递减的双端队列。为了高效获得最大值,需要维护一个单调递减的双端队列qmax。先把 qmax 里所有比 value小的尾部元素全部弹掉。再把 value 加到 qmax 的尾部。qmax 的队头永远是当前队列最大值。时间复杂度:O(1)空间复杂度:O(n)普通队列 q 用来正常入队/出队。

2025-11-17 10:18:40 199

原创 LC.1438 | 绝对差不超过限制的最长连续子数组 | 队列 | 双单调队列/滑动窗口

做的时候我先做的中等题,哼哧哼哧做完题,再去做困难题,看完题目,第一反应:Are you kidding me?通过队首元素快速获取当前窗口的最大值和最小值,判断是否合法。在 L移动之前,如果最大值或最小值的索引正好是旧的左边界 L,则必须将其从对应的单调队列队首中移除。问题,窗口的右边界 R(对应代码中的i)不断向右扩展,而左边界 L(对应代码中的。思路:一个子数组中任意两元素的最大绝对差,实际上等于该子数组中的。一个整数,表示满足条件的最长连续子数组的长度。,队首索引对应窗口内最大值。

2025-10-29 22:31:38 141

原创 LC.239 | 滑动窗口最大值 | 队列 | 单调队列/滑动窗口

在处理完当前窗口的最大值后,如果队首元素的索引等于当前窗口的起始位置 i - k + 1,说明它即将离开窗口,必须将其弹出。要求:将大小为 k的滑动窗口从数组的最左侧移动到最右侧。因为如果一个元素比新元素小,并且在新元素之前入队,那么它永远不可能成为最大值(它会被新元素遮挡),所以可以直接移除。也是用到了单调队列解决,题目难度中等,但我觉得可以给个困难,然后LC.239这一题给个中等难度。输入:一个整数数组 nums 和一个整数 k,表示滑动窗口的大小。输出:一个整数数组,包含所有滑动窗口中的最大值。

2025-10-29 22:25:30 296

原创 LC.1047 | 删除字符串中的所有相邻重复项 | 栈 | 字符串操作

要求:执行重复删除操作:选择两个相邻且相同的字母并删除它们。这个操作可以在剩余的字符串上重复执行,直到无法继续删除为止。思路:有点像连连对消除,两个一消除,还容易引起连锁反应,使用栈处理挺好。(当然直接用string 模拟栈,代码更简洁,最后返回ans的时候,可以省去出栈及reverse环节。如果当前字符 c 与栈顶字符相同,则说明发现了一对相邻重复项,应执行删除操作。如果栈为空,或当前字符 c与栈顶字符不相同,则将 c压入栈中。:依次读取输入字符串 s中的每个字符 c。输出:一个字符串,表示最终的结果。

2025-10-29 00:17:46 165

原创 LC.225 | 用队列实现栈 | 队列 | 队列模拟

思路:两个队列来回倒腾,注意每次入栈就交换一次存储队列,使其时刻先入栈的元素在栈顶。输出:实现一个符合上述操作要求的栈类。

2025-10-29 00:11:14 187

原创 LC.933 | 最近的请求次数 | 队列 | 滑动窗口

在时间 $t$ 添加一个新请求,并返回在时间区间 [t-3000, t]内发生的请求数(包括新请求)。输入:一个时间戳 t,表示一个新请求发生的时间(毫秒)。保证每次调用的 t 值都比之前的值大。:窗口的右边界是当前时间 t,左边界是 t-3000。由于时间戳 t 总是递增的,适合使用。时间复杂度:O(1)空间复杂度:O(n)输出:实现一个符合上述操作要求的。(先进先出)来存储请求的时间戳。:初始化计数器,请求数为 0。

2025-10-29 00:06:16 191

原创 LC.1700 | 无法吃午餐的学生数量 | 队列 | 计数模拟

思路:因为students队列是不断循环的,所以只要能取餐就一定会循环到,根本不需要考虑students里的顺序,直接计数统计喜欢1和喜欢0的人数。如果学生不喜欢栈顶三明治,他会放回三明治,并回到队列尾部。当队列中的所有学生都不喜欢栈顶三明治时,过程停止。要求:学生排成一个队列,三明治堆成一个栈。如果栈顶三明治是 0,但没有喜欢 0 的学生 (如果栈顶三明治是 0,且有喜欢 0 的学生 (如果学生喜欢栈顶三明治,他会拿走并离开队列。输出:一个整数,表示无法吃午餐的学生数量。三明治类型为 1 的情况同理。

2025-10-29 00:04:04 160

原创 LC.232 | 用栈实现队列 | 栈 | 栈模拟

思路:队列是先进先出(FIFO),而栈是后进先出(LIFO)。利用两个栈,可以通过“倒腾”数据来实现 FIFO 顺序。我写的非常简单粗暴,可以优化写法,提前准备好出栈数据,不必次次倒腾。

2025-10-28 23:58:41 175

原创 LC.1670 | 设计前中后队列 | 队列 | vector

来存储队列元素,因为动态数组支持在任意位置进行插入和删除操作。可能很取巧,但是题目也没不让用啊。输出:实现一个符合上述操作要求的前中后队列类。时间复杂度:O(n)空间复杂度:O(n)输入:无,构造函数接受无参数。要求:设计一个队列类。

2025-10-28 23:52:09 312

原创 LC.641 | 设计循环双端队列 | 队列 | 数组模拟

要求:设计你的实现循环双端队列类 MyCircularDeque。它是一种能从两端分别插入和删除元素的双向队列,使用固定大小的数组模拟环形结构。你需要实现题目要求的所有操作方法。模拟环形结构,在 LC.622题 设计循环队列 的基础上新增一下出队入队函数即可。输入:一个整数 k,表示双端队列的最大容量。输出:实现一个符合上述要求的循环双端队列类。时间复杂度:O(1)空间复杂度:O(k)

2025-10-28 23:47:25 204

原创 LC.622 | 设计循环队列 | 队列 | 数组模拟

循环队列实际上是存储在一个固定大小的数组中,并被当作首尾相接的环形结构。enQueue(value):向循环队列插入一个元素。MyCircularQueue(k):构造器,设置队列长度为 k。deQueue():从循环队列中删除一个元素。Front():从队列中获取队首元素。如果队列为空,返回 -1。Rear():获取队尾元素。isEmpty():检查循环队列是否为空。输入:一个整数 k,表示队列的最大容量。isFull():检查循环队列是否已满。输出:实现一个符合上述要求的循环队列类。

2025-10-28 23:44:44 117

空空如也

空空如也

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

TA关注的人

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