- 博客(128)
- 收藏
- 关注
原创 LeetCode 207. 课程表
视频: https://leetcode.cn/problems/course-schedule/solutions/359392/ke-cheng-biao-by-leetcode-solution/?envType=study-plan-v2&envId=selected-coding-interview这个问题是经典的拓扑排序问题,本质是判断有向图中是否存在环。题目要求判断是否能完成所有课程的学习,其中每个课程可能有前置要求(依赖关系)。拓扑排序 + BFS(卡恩算法):构建邻接表和入度数组:初始化队
2025-07-12 12:52:59
1007
原创 LeetCode 278. 第一个错误的版本
可以判断某个版本是否错误。由于版本号是有序的,且错误版本之后的所有版本都是错误的,因此可以使用。这种方法高效且简洁,是解决有序数组中查找特定元素问题的经典思路。这个问题要求找到第一个错误的版本,其中给定一个 API。指向同一个位置,即第一个错误版本。指向错误版本,因此更新时直接将。分别指向第一个和最后一个版本。分别表示版本范围的左右边界。在每次循环中,计算中间版本。计算中间值,避免整数溢出。高效地定位第一个错误版本。相遇时,循环结束,此时。都很大时发生整数溢出。即为第一个错误版本。,且第一个错误版本是。
2025-07-11 10:56:24
469
原创 LeetCode 8. 字符串转换整数 (atoi)
在字符串处理中,自动机特别适合处理需要根据输入字符序列按特定规则转换状态的问题。这个问题要求将字符串转换为 32 位有符号整数,需要处理前导空格、符号位、数字字符以及溢出情况。符号位仅在第一个非空格字符处生效,其他位置的符号字符会被视为非数字字符而终止转换。当需求变化时(如增加新的状态或转移规则),只需修改转移表,无需大规模重构代码。在处理具有明确状态转换规则的问题时,自动机是一种强大且优雅的解决方案。将复杂的条件判断转化为明确的状态转移表,避免嵌套的。一旦遇到非数字字符,立即停止转换,避免无效处理。
2025-07-10 19:47:47
1172
原创 LeetCode 151. 反转字符串中的单词
这个问题要求将给定字符串中的单词顺序反转,同时移除多余空格,使得每个单词之间只有一个空格,且字符串首尾无空格。整体反转+单词反转的组合巧妙地实现了单词顺序的反转,同时保持单词内容正确。将整个字符串反转,此时单词顺序已反转,但每个单词内部字符顺序也被反转。:通过三次反转操作实现单词顺序的反转,同时处理多余空格。将字符串中的多余空格去除,只保留单词间的单个空格,并调整字符串长度。遍历字符串,对每个单词进行局部反转,恢复单词的原始顺序。这种方法高效且符合题目要求,是解决此类问题的经典思路。
2025-07-07 23:01:25
531
原创 C++ bitset 模板类
是 C++ 标准库中的一个模板类,用于处理固定大小的位集合(Bit Set)。:标准 ASCII 码使用 7 位表示 128 个字符(0~127),扩展 ASCII 码用 8 位表示 256 个字符(0~255)。在 LeetCode 266 题中,它通过位翻转操作巧妙地统计了奇数次字符的数量,代码简洁且效率极高。是一个非常关键的数值,它在字符编码、位操作等场景中具有特殊意义。在 LeetCode 266 题(回文排列)中,输入字符串通常由常见字符组成,(对应 UTF-32),但需注意空间开销的显著增加。
2025-07-04 18:36:28
919
原创 leetcode 295. 数据流的中位数
大顶堆可以比小顶堆多1个元素(奇数个元素时)小顶堆不能比大顶堆多元素,最多相等(偶数个元素时)当大顶堆大小超过小顶堆大小1以上时需要调整(+1的由来)当小顶堆大小超过大顶堆时需要调整(不需要+1,因为不允许小顶堆更大)大顶堆始终保存较小的一半数字小顶堆始终保存较大的一半数字可以在O(1)时间内获取中位数理解这些条件背后的原理,有助于更好地掌握双堆数据结构在中位数查找中的应用。你修改后的代码在每次插入新元素时立即排序,虽然简化了中位数查找的逻辑,但整体效率仍然不如双堆实现。这是因为。
2025-06-27 17:13:28
1087
原创 leetcode 233. 数字 1 的个数
我们知道,对于从 0 开始每 1000 个数,「百位」上的数字 1 都会出现 100 次,即数的最后三位每 1000 个数都呈现 [000,999] 的循环,其中的 [100,199] 在「百位」上的数字为 1,共有 100 个。n 拥有 1234 个这样的循环,每个循环「百位」上都出现了 100 次 1,这样就一共出现了 1234×100 次 1。,它是一个 10 位整数,因此我们可以考虑枚举每一个数位,分别统计该数位上数字 1 出现的次数,最后将所有数位统计出的次数进行累加即可得到答案。
2025-06-27 15:07:10
510
原创 leetcode 65
代码解析:使用确定有限状态自动机验证有效数字这段代码通过**确定有限状态自动机(DFA)**来验证一个字符串是否表示有效数字。下面我将从状态定义、转移规则到完整逻辑逐步解析:DFA 是一种计算模型,它包含:这个解法将字符串处理过程划分为9个状态,通过转移表定义状态间的转换规则,最终根据结束状态判断是否有效。状态用整数表示(0-8),每个状态对应数字字符串的一个解析阶段:外层 索引表示当前状态(0-8)内层 存储当前状态接受的字符类型及其对应的下一状态字符类型包括::数字(0-9):符号(
2025-06-26 13:06:44
813
原创 C++ 中 enum 语法
在 C++ 中,enum(枚举)是一种用户定义的类型,用于将一组命名的整数常量组合在一起。它提供了一种创建具有明确语义的符号化常量的方式,使代码更易读、更安全。以下是 C++ 中enum一、基础枚举(Traditional Enum)1. 定义语法enum 枚举名 {枚举常量1,枚举常量2,枚举常量3 = 特定值, // 可选赋值...2. 示例// 定义枚举类型表示颜色RED, // 默认为0GREEN, // 默认为1BLUE = 5, // 显式赋值为5。
2025-06-26 12:12:51
1111
原创 C++正则表达式语法
在C++中,正则表达式是处理文本模式匹配和字符串操作的强大工具。C++11及以后的标准库提供了。头文件,支持正则表达式的使用。通过掌握这些规则,您可以在C++中灵活使用正则表达式处理各种文本匹配问题。避免了对反斜杠的双重转义,使正则表达式更易读。转义(在C++字符串中需用双反斜杠。定义捕获组,可以提取匹配的子串。具有特殊含义的字符,需用反斜杠。C++11引入的原始字符串语法。用于表示一个正则表达式对象。
2025-06-26 11:55:20
808
原创 正则表达式,`[]`(字符类)和`|`(或操作符)
单个字符 | 整个子表达式(可以是多个字符) || 通常更快(直接索引字符集) | 较慢(需依次尝试多个子表达式) || 字符级的多选(如密码强度检查) | 字符串级的多选(如匹配不同单词) |表示取反 | 无直接否定形式,需用。在需要高效匹配单个字符的多选情况时,优先使用字符类。中的任意一个,可以匹配多个字符组成的字符串。,只能匹配单个字符。
2025-06-26 11:41:08
1285
原创 leetcode 1823. 找出游戏的获胜者 (约瑟夫环)
根据我们的映射规则,映射之前的序列中最后剩下的数字f’(n-1,m)=p-1[f(n-1,m)]=[f(n-1, m)+k+1]%n,把k=(m-1)%n代入得到f(n,m)=f’(n-1,m)=[f(n-1,m)+m]%n。,n-1,0,1,…由于这个序列的规律和前面最初的序列不一样(最初的序列是从0开始的连续序列),因此该函数不同于前面的函数,记为f’(n-1,m)。最初序列最后剩下的数字f(n,m)一定是删除一个数字之后的序列最后剩下的数字,即f(n,m)=f’(n-1,m)。
2025-06-23 12:06:05
366
原创 LeetCode 238题「除自身以外数组的乘积」
本题通过两次遍历数组分别计算左右乘积,巧妙地在不使用除法的情况下实现了OnO(n)On的时间复杂度。空间优化版本进一步将空间复杂度降至O1O(1)O1,是该问题的最优解法。
2025-06-20 15:47:29
465
原创 LeetCode 47.全排列 II
LeetCode 47.全排列 II 是一个经典的回溯算法问题,要求生成一个包含重复数字的数组的所有不重复的全排列。与普通的全排列问题(LeetCode 46.全排列)不同,这个问题需要处理数组中的重复元素,避免生成重复的排列。问题描述给定一个可包含重复数字的序列nums,按任意顺序返回所有不重复的全排列。示例示例 1:示例 2:解题思路• 排序:首先对数组进行排序,这样可以方便地处理重复元素。如果两个相邻的元素相同,那么在生成排列时可以跳过重复的分支。
2025-06-19 11:18:52
614
原创 c++ make_unique用法
/ 自定义删除器// make_unique不支持自定义删除器// 错误// 正确方式:直接构造unique_ptr异常安全:防止构造函数抛出异常导致内存泄漏// 若 new A 成功,new B 抛出异常,则 A 会泄漏 process(std :: make_unique < A >() , std :: make_unique < B >());// 安全。
2025-06-16 13:18:54
717
原创 智能指针 c++
智能指针是现代 C++ 内存管理的核心工具,正确使用可消除 90% 以上的内存管理问题。头文件中,用于自动管理动态分配的内存,防止内存泄漏。智能指针是 C++11 引入的内存管理工具,位于。
2025-06-16 13:11:20
697
原创 shared_ptr weak_ptr
相互引用时,会形成循环引用,导致引用计数无法归零,从而产生内存泄漏。:在可能存在双向引用的场景中,至少有一个方向使用。来打破循环引用,确保内存能够正确释放。
2025-06-16 13:08:17
348
原创 LeetCode 48. 旋转图像
此方法简洁高效,严格满足原地操作要求,是旋转矩阵的最优解法。完成,即直接修改输入矩阵,不使用额外空间。的二维矩阵表示图像,要求将图像。
2025-06-15 22:10:37
460
原创 scanf 读取字符串
需求推荐方法示例代码读取不含空格的字符串scanf+ C风格字符串读取含空格的字符串scanf+ 扫描集直接使用std::cin或getline建议:在C++中优先使用std::cin和getline,它们更安全且直接支持。仅在性能敏感或兼容C代码时使用scanf。
2025-06-14 18:31:09
765
原创 几种经典排序算法的C++实现
函数中,你可以取消注释相应的排序函数调用来测试不同的排序算法。选择排序(Selection Sort)插入排序(Insertion Sort)冒泡排序(Bubble Sort)快速排序(Quick Sort)归并排序(Merge Sort)
2025-06-13 22:20:02
325
原创 std::sort 默认排序方式
函数原型该函数使用默认比较函数operator<对元素进行比较,实现升序排序。比较函数的要求:必须是一个严格弱序关系!(a < a)反对称性:若a < b,则!(b < a)传递性:若a < b且b < c,则a < c示例:对结构体排序int age;// 按年龄升序,年龄相同时按名字升序if (a.age!std::sort默认升序:使用operator<实现元素的升序排列。底层实现:introsort,保证最坏情况下O(n log n)的时间复杂度。
2025-06-12 18:12:02
1155
原创 unordered_map添加元素
简单覆盖:使用[]运算符。安全插入:使用insert()或emplace(),并检查返回值。批量操作:使用或迭代器范围。性能优化:复杂对象优先使用emplace(),批量插入优先使用。通过合理选择插入方法,可以确保代码的安全性和性能。
2025-06-12 15:41:57
510
原创 leetcode 169. 多数元素
设数组长度为n,多数元素为target,出现次数为m,则m > n/2。其他元素统称为non-target,总出现次数为k = n - m,则k < m(因为。
2025-06-12 15:09:08
1182
原创 LeetCode 137 有限状态自动机解法原理详解
ones = (0 ^ num) & ~1 = num & 0 = 0,twos = (1 ^ num) & ~0 = 1 ^ num,等价于twos = (1 + num) % 3(num=1时,1→0)。ones = (ones ^ num) & ~0 = ones ^ num,等价于ones = (ones + num) % 3(当num=1时,0→1,1→0)。对于只出现一次的数字:其所有二进制位仅在ones中记录为1,twos中为0,因此ones即为该数字。ones:记录出现1次的二进制位集合。
2025-06-12 10:10:42
1030
原创 const auto& 和 auto
在C++中,遍历容器时使用是一种常见写法,而“不用引用”(即使用)在某些场景下也是可行的。下面从语法差异、性能影响、适用场景三个方面详细解释:2. (值传递)类型:值类型,复制元素,可修改副本(不影响原容器)。语法:,直接复制元素。示例:二、为什么推荐使用?1. 性能优化引用不复制元素:当容器元素是大型对象(如字符串、自定义类)时,值传递的复制开销很高:2. 逻辑安全修饰确保不会意外修改容器元素,符合“遍历不应修改数据”的原则:三、什么情况下可以不用引用(使用)?
2025-06-11 19:32:36
919
原创 遍历 unordered_map
遍历的核心是使用迭代器或基于范围的for循环,推荐使用C++11的auto和引用语法来简化代码。需要注意其无序性和迭代器失效问题,根据场景选择合适的遍历方式。
2025-06-11 19:24:56
983
原创 leetcode 768. 最多能完成排序的块 II
需要将前面的块合并,确保块的最大值单调递增。运行上述代码可观察到每一步的栈变化,验证整个处理过程。,从而保证排序后整体有序。例如,若第五个元素是。让我们一步步复现单调栈解法在输入。,确保后续块的最大值必须。1 == 栈顶(1)1 == 栈顶(1)
2025-06-11 18:58:00
347
原创 leetcode 135. 分发糖果
LeetCode 135题“分发糖果”要求给一排孩子分发糖果,每个孩子至少得到1个糖果,且相邻孩子中评分高的孩子必须获得更多糖果,求最少需要多少糖果。这种方法通过两次遍历,巧妙地解决了相邻孩子之间的比较关系,确保了使用最少的糖果数。这种方法保证了每个孩子与相邻孩子的比较条件都被满足,同时使用最少的糖果数。
2025-06-11 16:12:39
399
原创 strs[0] == “0“是否为字符串内容比较
如果是string类型:直接用==比较内容,无需额外处理。如果是类型用比较内容。或转为string。避免依赖指针地址比较:除特殊场景外,指针地址的比较结果不可靠(如 LeetCode 179 中必须比较内容)。通过类型判断比较逻辑,可避免因类型混淆导致的 bug。
2025-06-11 12:09:11
634
原创 “0“ == “0“
"0" == "0"的结果不确定:取决于编译器是否合并相同字符串字面量的地址,可能为true或false。'0' == '0'恒为true:字符直接比较ASCII码值,与内存地址无关。字符串比较应基于内容而非指针,使用或strcmp确保逻辑正确。
2025-06-11 11:58:09
971
原创 ‘0‘和“0“
单引号'0'是一个字符,类型为char,存储ASCII码值。双引号"0"是一个字符串,类型为,包含字符和结束符。混淆两者会导致编译错误或运行时未定义行为,需根据场景正确使用。理解这些区别对于处理C++中的字符和字符串操作至关重要,特别是在涉及输入解析、数值转换或字符串处理的算法题中。
2025-06-11 11:52:40
1051
原创 c++ lambda
C++的lambda表达式是一种灵活、高效的创建匿名函数的方式,特别适合在需要临时函数对象的场景中使用。掌握其语法和捕获机制,可以编写出更简洁、更具表现力的代码。
2025-06-11 11:33:34
512
原创 LeetCode 11题“盛最多水的容器”
LeetCode 11题“盛最多水的容器”要求在给定的一组垂直线中,找出两条线,使得它们与x轴共同构成的容器可以容纳最多的水。容器的容量由两条线之间的距离和较短线的高度决定。最直接的方法是枚举所有可能的线对并计算其容量,但这种方法的时间复杂度为O(n²),效率较低。这种方法通过贪心策略,逐步缩小搜索空间,确保在O(n)时间内找到最优解。这种方法的时间复杂度为O(n),因为只需要遍历一次数组。
2025-06-10 21:50:44
405
原创 LeetCode 240 搜索二维矩阵 II
同理,从左下角(最后一行的第一列)开始搜索也可以达到相同效果,但从左上角或右下角开始无法有效缩小搜索区域。LeetCode 240题要求在一个二维矩阵中搜索目标值。这种方法通过逐步缩小搜索区域,高效地找到目标值或确定其不存在。每次迭代要么行增加1,要么列减少1,最多需要遍历m行+n列。右上角的元素是该行的最大值、该列的最小值。该矩阵的特殊性质(每行每列均有序)允许我们从矩阵的。(m和n分别为矩阵的行数和列数)。(或左下角)开始搜索,将时间复杂度优化到。只需要常数级的额外空间。
2025-06-10 19:53:06
680
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅