- 博客(73)
- 收藏
- 关注
原创 二分查找系列一
本文系统梳理了二分查找的五大经典题型,涵盖朴素模板、左右边界查找、平方根、插入位置及山脉峰顶索引。重点强调细节处理:中点公式选择(防溢出与死循环)、循环条件设计及边界判断。虽看似简单,实则易错,需结合具体场景灵活应用。所有题目时间复杂度均为O(log n),空间复杂度O(1),体现二分查找高效性与普适性。
2026-09-29 20:02:20
235
原创 滑动窗口系列二--末尾(3道题)
本文总结了三道滑动窗口经典题目的解法:LCR015(字母异位词)、30(串联单词子串)和LCR017(最小覆盖子串)。均采用双指针+哈希表优化,通过维护窗口内字符频次与有效匹配数,实现O(n)时间复杂度。核心思想为“同向双指针”与“滑动窗口”,分别处理固定长度匹配、多字符串拼接及字符种类覆盖问题,空间复杂度均为O(1)~O(n),代码逻辑清晰,极具代表性。
2026-09-23 17:51:04
171
原创 滑动窗口系列一(5道题)
本文通过五道经典滑动窗口题,系统讲解其核心思想——同向双指针与状态保持。从长度最小子数组到无重复字符最长子串,再到最大连续1的个数III、将x减到0的最小操作数及水果成篮,逐步揭示滑动窗口的通用解题框架:进窗口、判断、出窗口、更新。强调理解“为何可用滑动窗口”比记忆模板更重要,倡导通过演练与模仿建立算法思维,最终实现从认知到熟练的跨越。
2026-09-22 00:58:15
112
原创 特殊类的实现(c++)
设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的 总结。为什么会产生设计模式这样的东西呢?就像人类历史发展会产生兵法。最开始部落之间打 仗时都是人拼人的对砍。后来春秋战国时期,七国之间经常打仗,就发现打仗也是有套路的,后 来孙子就总结出了《孙子兵法》。孙子兵法也是类似。使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。设计模 式使代码编写真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。
2026-06-25 17:14:34
181
原创 Docker Note
Docker入门与实践摘要 本文介绍了Docker的基本概念和常用容器命令。Docker是一种容器化技术,通过操作系统虚拟化实现资源隔离,比传统虚拟机更轻量高效。文章解释了虚拟化与容器化的区别及优势,包括提高资源利用率、快速启动、便于维护等。 重点讲解了20个常用Docker容器命令及其使用场景: 容器生命周期管理(create/start/stop/restart/kill) 容器监控与检查(logs/top/stats/inspect) 文件操作(cp/diff/commit) 批量操作技巧(命令替换语
2026-06-06 16:38:44
302
原创 进程控制(Linux)
本文摘要(150字): 本文系统介绍了Linux进程管理的核心机制。首先讲解了fork函数的工作原理,包括写时拷贝的实现细节和进程地址空间的概念。随后分析了进程终止的三种场景及exit/_exit函数的区别。重点阐述了进程等待机制,通过示例代码演示了如何避免僵尸进程。最后详细讲解了进程替换的7种exec系列函数,包括其参数特点和使用场景,并通过多进程示例展示了程序替换的实际应用。文章还涉及了环境变量的处理方式和多文件编译技巧,全面覆盖了Linux进程创建、管理到替换的全流程。
2025-09-21 19:17:10
723
原创 环境变量_进程地址空间
本文主要介绍了Linux环境变量的概念和使用。环境变量是系统提供的全局变量,具有继承性,常见变量包括PATH(系统指令搜索路径)和HOME(工作目录)。文章详细讲解了环境变量的查看、添加方法,以及通过C语言程序获取环境变量的三种方式。同时区分了环境变量与本地变量的不同特性,并解释了内建命令(如cd)由bash直接执行的特点。此外,还探讨了进程地址空间的虚拟地址概念,说明父子进程通过写时拷贝机制共享代码但数据独立。最后提及了缺页中断和空间分布图等操作系统底层机制。
2025-09-10 16:39:45
831
原创 进程状态(Linux)
Linux进程状态主要分为运行(R)、睡眠(S/D)、停止(T/t)、死亡(X)和僵死(Z)状态。其中运行状态表示进程在运行队列中;睡眠状态分为可中断(S)和不可中断(D)两种;T/t状态表示进程被停止或调试;Z状态是进程终止后等待父进程回收的临时状态。进程切换涉及上下文保存和恢复,通过时间片轮转实现并发执行。僵尸进程和孤儿进程可能导致内存泄漏,需及时处理。CPU通过寄存器保存进程上下文,确保进程切换后能正确恢复执行。
2025-09-10 16:12:04
1152
原创 智能指针(c++11)
智能指针是C++中用于自动管理动态内存的RAII(资源获取即初始化)机制。文章介绍了C++98到C++11智能指针的发展历程,包括auto_ptr(已废弃)、unique_ptr(禁止拷贝)、shared_ptr(引用计数)和weak_ptr(解决循环引用)。其中重点分析了shared_ptr通过引用计数实现安全拷贝,以及weak_ptr如何避免循环引用导致的内存泄漏。文章还演示了自定义删除器的使用场景,并对各版本智能指针的特性进行了总结对比,推荐在C++11及以上版本优先使用unique_ptr和shar
2025-09-02 15:36:01
1008
原创 c++11特性
本文主要介绍了C++11的新特性,包括初始化列表、右值引用、移动语义、完美转发、可变参数模板、lambda表达式和包装器等。其中重点讲解了右值引用和移动语义如何通过资源转移提高效率,以及lambda表达式的语法和使用场景。还介绍了function包装器可以将不同类型统一处理,bind可以改变参数顺序等功能。这些新特性使C++在性能和易用性上都有显著提升,为开发者提供了更强大的工具。
2025-09-01 09:25:48
766
原创 哈希(unordered_map/set)
哈希表是一种高效的数据结构,通过哈希函数将数据映射到特定位置,实现O(1)时间复杂度操作。文章详细介绍了哈希函数(直接定址法、除留取余法等)、哈希冲突(闭散列和开散列两种解决方法)及其代码实现。重点分析了线性探测和二次探测在闭散列中的应用,以及链地址法在开散列中的实现。最后展示了如何基于哈希表封装unordered_map和unordered_set,包括迭代器设计、插入删除操作等核心功能实现。
2025-08-26 15:12:06
746
原创 排序(数据结构)
本文介绍了常见比较排序算法及其实现。插入排序(最好O(n),最坏O(n^2))采用边比较边移动方式;希尔排序通过分组插入优化到O(n^1.3)。选择排序始终O(n^2)性能最差。冒泡排序优化后最好O(n),但插入排序在部分有序时更优。堆排序采用建堆策略,时间复杂度O(n*logn)。快速排序基于分治思想,原始Hoare版本存在栈溢出风险,改进采用三数选中和随机选key策略,衍生出挖坑法和前后指针法,推荐使用后者。文章还分析了各算法的时间复杂度和适用场景,强调实际应用中应根据数据特点选择合适的排序方法。
2025-08-22 20:48:05
1106
原创 map_set
本文深入探讨了map和set基于红黑树的封装实现。首先对比了红黑树与AVL树的优势,指出红黑树在底层数据结构中的广泛应用。文章详细展示了map和set的基本使用方法,包括插入、删除、查找等操作,并强调了它们使用的双向迭代器特性。重点分析了红黑树模板的封装过程,包括结点定义、旋转操作和平衡控制,特别讲解了迭代器的设计实现,如何通过模板参数区分普通迭代器和const迭代器。最后,文章比较了map和set在迭代器设计上的差异,指出set由于key值唯一不可变的特点,其迭代器都是const版本。通过封装红黑树,实现
2025-08-22 20:33:06
574
原创 RBT红黑树(c++)
之前我们已经学习过二叉搜索树和AVL树,我们知道AVL树的时间复杂度优于二叉搜索树,并且AVL树的实际运用情况也很广,那为啥我们还要学习红黑树呢?AVL树的旋转次数实际上是比较多的,对效率的影响是有一定的影响,而且他的条件是严格的平衡二叉树,对于大量使用查找的场景,效率还可以,但是如果设计到大量的插入场景,旋转次数是占比很大的。
2025-07-21 14:53:04
832
原创 AVL树c++
1.一颗AVL树的左右子树都是AVL树2.左右子树的高度差的绝对值不超过1一般来说,为了实现左右子树的高度差的绝对值不超过1,需要使用一个平衡因子,来控制。这里实现高度平衡的方式不唯一,有的地方会直接计算两树的高度差,不会使用平衡因子。但是平衡因子大部分情况都会使用,本问介绍的也是平衡因子的方法。啥是平衡因子?如图,他就是一个AVL树结点里的一个变量,他的值是0,1,-1。1.值为1的时候表示右子树的高度-左子树的高度=12.值为0的时候表示右子树的高度-左子树的高度=0。
2025-07-21 14:52:32
1039
原创 二叉树进阶刷题03(构建二叉树与双向链表转换)
本文分析了二叉树构造与转换的两类问题:1)通过前序/后序和中序遍历序列构造二叉树。前序+中序时,用前序确定根节点,中序划分左右子树,递归构建时需注意下标关系和传参方式;后序+中序则需先构建右子树再左子树。2)将二叉搜索树转换为双向链表。采用中序遍历,在递归过程中用prev指针记录前驱节点,修改节点左右指针完成双向链接,注意处理头节点和避免循环引用。两题都强调了递归实现的关键点和易错点,如边界条件、参数传递顺序和指针操作时序等。
2025-07-02 14:46:05
1118
原创 二叉树进阶刷题02(非递归的前中后序遍历)
本文介绍了二叉树前序、中序、后序遍历的非递归实现方法。通过分析递归过程,将其分解为"递"和"归"两个阶段,使用栈来模拟递归调用栈。前序遍历在访问节点时直接输出,中序遍历在弹出栈顶元素时输出,后序遍历则需要使用prev指针记录上次访问的节点来判断访问时机。三种遍历都采用类似的双层循环结构:外层控制遍历是否完成,内层处理左子树入栈。关键区别在于节点访问时机的选择:前序在入栈时访问,中序在出栈时访问,后序需确保右子树已访问才访问当前节点。文章强调后序遍历的实现难度较大,需要
2025-06-29 22:48:56
688
原创 c++多态(表面-->底层)
我们来总结下多态,这里的知识确实有点复杂。首先我们来总结下啥是多态,上文提到了静态和动态绑定。我们的多态总的说是为静态和动态的,静态的多态就是函数重载,动态的多态就是虚函数指针调用。这里我们把多态分成静态和动态,是从他的便利性和灵活性出发的。回到起点,我们说多态就是不同的人去干一件事,产生了不同的效果。虚函数表可以实现对象,那我们的函数重载也可以实现我们平常的变量调用。那多态的原理是啥呢?还是从静态和动态两个角度讲,静态就是函数重载,动态就是虚函数表。
2025-06-10 20:36:03
720
原创 c++继承
摘要:继承是面向对象编程的重要概念,它允许子类继承父类的成员并扩展新功能。文章详细讲解了继承的定义、语法及三种继承方式(public/protected/private)的影响。重点分析了子类与父类的对象转换机制(切片操作),作用域规则(成员隐藏现象),以及派生类默认成员函数(构造/拷贝/赋值/析构)的实现要点。特别讨论了菱形继承带来的数据冗余问题,通过虚继承和虚基表指针的机制解决。文章指出虽然继承机制源自现实生活,但多继承在实际编程中可能带来复杂性,建议谨慎使用。全文结合代码示例,系统性地阐述了C++继承
2025-06-02 14:37:56
682
原创 STL_stack和queue(deque priority_queue)
本文主要介绍,本人的学习心得和知识汇总,本篇博文对于STL知识的讲解侧重于难点,不会每一个都细细讲解。本文主要对适配器设计模式展开讲解,对反向迭代器和优先级队列重点讲解。STL对栈和队列的设计不同于之前c语言设计的栈和队列,不再是手搓结构,我们STL借用别人的容器实现,这就是适配器,要注意适配器是一种设计模式,是一种全新的东西,这也是我们要学习他的原因。
2025-05-30 15:20:10
1141
原创 list(c++)
本文主要介绍了STL中list容器的底层实现和使用方法。list是一个双向带头节点的链表,支持多种构造函数和迭代器操作。文章详细讲解了list的默认成员函数、迭代器设计、容量管理以及增删查改等操作。特别强调了迭代器的重要性,它是访问和操作list的核心工具。通过自定义迭代器类型,list实现了对链表元素的统一访问方式,极大简化了编程复杂度。文章还通过代码示例展示了list的基本操作,并指出学习list的关键在于理解其底层设计理念,尤其是迭代器的实现。
2025-05-22 18:04:22
1041
原创 vector(c++)
本文主要介绍了C++标准模板库(STL)中的vector容器,包括其基本定义、构造函数、迭代器使用、容量管理、增删查改操作以及迭代器失效问题。vector是一种动态数组,使用连续存储空间存储元素,支持动态扩展和收缩。文章详细讲解了vector的多种构造函数、迭代器的使用方式、容量管理函数(如resize和reserve)以及增删查改操作(如push_back、pop_back、insert和erase)。特别强调了迭代器失效问题,指出在insert和erase操作后,迭代器可能会失效,使用失效的迭代器会导致
2025-05-17 17:16:40
1095
原创 string(c++)
string 并不是STL库里的一个容器,而是游离于STL的一个容器,这是历史原因导致的。因为他的研发比STL早,但是后面大佬们研发出了STL。string为了兼容STL就做了一些调整,一贯的作风就是向上兼容。因此,他相比STL其他的容器会有点冗余。提问:string就是字符串吗?他和字符串一摸一样吗?答案是:不是,大部分情况一摸一样。string和字符串是有区别的,输出字符串是以\0为结束标志,但是string是一个容器,他以size为结束标志。
2025-05-15 23:24:13
996
原创 二叉树的初步学习
二叉树的学习会用到大量的递归,这里也是练习递归的一个很好的章节。也许你可能会感到使用递归有点困难。这是因为你还没有理会到递归的精髓。这里实际上使用递归解决这些遍历是很简单的,如果使用非递归解决二叉树的问题,那才是真正的上难度了。
2025-04-13 19:58:22
889
1
原创 类和对象进一步了解c++
上面三个成员都有一个特点就是再创建的时候必须被初始化,这是c++规定的。对于引用和const我们清楚,const修饰的变量具有常性,必须再定义的时候初始化,引用也必须初始化,他不可以给空指针。但是自定义类型呢?对于自定义类型是看情况的,如果你的自定义类型没有默认构造函数,那我们就无法自动调用构造函数。那怎么办呢?根据定义又必须要初始化。所以,初始化列表接很好的解决了问题。初始化列表就是专门用来初始化成员变量的地方。这里注意,初始化列表位置在构造函数上紧紧相连,他是构造函数的一部分,这是语法上的结构绑定。
2025-03-02 22:17:37
1190
1
原创 内存管理c/c++
new和delete是c++两个关键字,负责开辟动态空间和销毁空间,和malloc和free很像。于是,把他们封装成了函数,分别由new和delete调用,也就是说,new和delete的底层原理还是调用malloc和free。new和malloc的区别也是在这里,new会先开辟空间,再调用构造函数,而malloc只是单纯的开辟空间。对于服务器上的程序,长期运行的。比如王者服务器上的程序,你可想象一下,你无论在什么时候打开游戏都是可以正常运行的。如果,王者的服务器上的程序出现了一个内存泄漏的代码。
2025-03-02 22:15:51
724
原创 c++类和对象初步了解
这里的默认析构函数就是编译器生成析构函数编译器生成的析构函数,也是不会对内置类型做处理的,只会让自定义类型去调用他的析构函数。
2025-02-19 22:32:26
1073
原创 c++入门
c++的出现主要最初是为了解决c语言的不足,但随着之后逐渐的发展,成为了一门成熟的语言。因为,c++最初是为了解决c语言的不足。所以,在c++入门学习主要了解c++解决那些c语言的不足。
2025-02-19 22:06:07
660
原创 今日写题06work(链表)
这几道题都是关于链表的,大多题目的思路都和双指针有关。所以,可见双指针在解决链表的一些题目上有很大作用。这可以当成一个题解的基本思路。从双指针出发,根据题目特点进行变型,解决题目。解决这类题目,画图也是一个很好的方法。当你在写代码前,先画图把思路弄清楚,会大大提高你代码的正确率。即使代码错了,也可以通过图来走读你的代码。如果都不行,我们再调试代码。这能提高你解决题目的效率,不然你很有可能是调试了两三个小时都发现不了问题。
2025-02-16 15:11:31
1142
原创 今日写题04work
使用双指针,prev,cur快慢指针解决。当cur不等于val,两个指针跳过。当等于val时,要考虑两种情况,一种是pos删,一种是头删除。pos删除就是正常情况,但头删是一种特殊情况,比如第一个数据就是等于val。所以,我们在这里分类处理。
2025-02-15 21:20:44
381
原创 队列Queue(c语言实现)
队列的实现和链表的实现很相似,但是不同之处是,他在继承了链表的优点之后又克服了链表的很多缺点,不如在求长度时就很方便,不用再一个一个遍历。
2025-02-15 16:24:23
1066
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅