算法基础
文章平均质量分 95
算法基础
软件架构师何志丹
我的源码、视频、博文、电子书可复用性、可理解性、可测试性皆强。优于工作,劣于竞赛。源码:https://gitcode.com/invite/link/a07392368f3a4ae295c0
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
字符串贪心:字典序 回文 括号
本文摘要:文章总结了C++中关于字典序、贪心算法、回文串、括号匹配等知识点,通过多个实际题目(如3170、2434、2663等题)讲解相关算法实现。内容涵盖字符串处理、动态规划、贪心策略等技术要点,并附有视频课程链接和测试环境说明,适合希望系统学习C++算法的读者参考。原创 2025-11-09 17:00:00 · 1228 阅读 · 0 评论 -
【动态规划】数位DP的原理、模板(封装类)
本文介绍了C++动态规划的几种解法,重点讨论了基于上下界处理的动态规划状态表示和转移方法。主要内容包括:1) 通过位数拆分处理不同范围的动态规划;2) 定义了4种边界状态(非界、下界、上界、上下界)及其转移规则;3) 提供了三种优化方法:公共前缀处理、范围方案数简化、前导零处理;4) 给出了两个通用模板类(CLowUperr和CUpperDP)的实现框架,支持自定义状态和边界条件处理。这些方法适用于处理数字范围相关的动态规划问题,能够有效降低时间复杂度至O(4N∑)。原创 2025-10-16 07:00:00 · 2359 阅读 · 52 评论 -
区间贪心:最多不相交区间、区间选点、区间合并、区间覆盖、区间分组
本文总结了C++中区间贪心算法的常见类型及解法:1)不相交区间选择(单组/多组),按右端点排序后贪心;2)区间选点问题,包括最少覆盖点和区间分配点;3)区间合并,按左端点排序后处理;4)区间覆盖,优先选择覆盖当前点且右端点最大的区间;5)区间分组,所有区间必须分组求最小组数。每种类型都给出了核心性质、算法思路及时间复杂度分析,并附相关例题。这些方法在解决如座位安排、毯子覆盖等问题中具有广泛应用。原创 2025-09-25 07:00:00 · 2417 阅读 · 53 评论 -
倍增算法(multiply)、树上倍增、最近公共祖先(LCA)、ST表、快速幂、矩阵快速幂
本文介绍了倍增算法的核心概念与应用场景,主要包括区间信息处理、树上倍增和快速幂三类。在区间信息处理中,通过预处理构建二维数组vMax来高效查询区间最大值,时间复杂度为O(NlogN)。树上倍增部分详细讲解了如何利用vGrand数组记录节点的多级祖先,并重点阐述了最近公共祖先(LCA)的高效求解方法,时间复杂度优化至O(logn)。文章还提供了完整的C++实现代码,包括CParents和C2Parents两个类,封装了倍增查询、层级计算、祖先查找等核心功能,支持在树结构中进行快速公共祖先查询。该算法适用于需要原创 2025-09-15 07:00:00 · 1831 阅读 · 55 评论 -
C++线段树(Segment Tree)二:静态开点、区间修改
本文介绍了C++线段树的实现方法,包括静态开点和区间修改(懒修改)技术。静态开点通过向量存储二叉树节点,节省空间。区间修改采用懒标记技术,最多遍历4logN个节点,通过回调接口OnUpdateBranch和OnUnionSet处理缓存更新。文章提供了线段树的封装类设计,包括基类CSegmentTree、单点更新类CSingeSegmentTree及其动态开点实现CSingeTreeSegmentTree,支持查询、更新等操作。回调接口定义了节点合并、叶子更新和缓存合并等功能,为线段树的灵活应用提供基础框架。原创 2025-09-12 15:30:00 · 1755 阅读 · 0 评论 -
C++线段树(Segment Tree)三:常用回调类及所有样例
本文介绍了C++线段树(Segment Tree)的实现方法,重点展示了多种回调类的设计。文章首先定义了ISegmentTreeCall基类及其派生类ISingleSegmentTreeCall和IRangleSegmentTreeCall,用于处理不同类型的线段树操作。随后详细介绍了针对不同需求的回调类实现,包括:最大值处理类(CMaxMax、CSetMax、CAddMax)、异或求和类(CXorCnt)、求和类(CAddSum、CSetSum)以及相乘求余类(CMulMod)。这些回调类实现了线段树的核原创 2025-09-12 07:00:00 · 1155 阅读 · 0 评论 -
C++线段树(Segment Tree)一:正确性证明、模板及封装类及样例
线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(logN)。而未优化的空间复杂度为2N,实际应用时一般还要开4N的数组以免越界,因此有时需要离散化让空间压缩。区间更新(查询)的时间复杂度是O(logn),使用懒惰法只会影响以下四类节点,每类节点数量都不超过logn。一,左边界及其祖先。二,右边界及其祖先。三,第一类的兄弟节点。四,第二类的兄弟节点。原创 2024-04-18 08:24:29 · 1681 阅读 · 40 评论 -
【倍增 桶排序】后缀数组
桶排序优化按v升序将sa[inx+len]放到sa[inx]中。 v由于已经是升序,故各桶内部无需排序。每轮时间复杂度:O(N),总时间复杂度:O(NlogN)。# DC原创 2025-08-21 07:00:00 · 2132 阅读 · 61 评论 -
C++并集查找
本文介绍了并查集(Union-Find)数据结构的基本概念和实现方法。主要内容包括:1) 并查集的基本操作find和union,用于处理动态连通性;2) 暴力实现方法及其时间复杂度分析;3) 两种优化策略:启发式合并(UNION BY RANK)和路径压缩(PATH COMPRESSION);4) 可撤销并查集的实现思路;5) 提供了三种封装类代码实现:普通并查集、实时更新节点的并查集、无向图并查集。文章通过数学归纳法证明了合并操作的正确性,分析了不同实现的时间复杂度,并给出了详细的C++代码实现,适合算法原创 2025-05-29 07:15:00 · 4169 阅读 · 60 评论 -
【数学 线性代数】差分约束
x系列是变量,y系列是常量,差分系统由若干如下不等式组成。x1-x2 <= y1 x2-x3 <= y2 $\cdots$原创 2025-03-17 07:00:00 · 3821 阅读 · 92 评论 -
【C++】树状数组的使用、原理、封装类、样例
性质五:f(j) < i <= j, f(j)中1的个数不会多于f(i)。性质二,f(x)= x&(x-1) ,即将最低位的1变成0,f(6)=4。令i的最后一个1是第k4位,只讨论比k4高的位,f(j)<=i,否则整个f(j)>i。比k4高的位f(i)等于i,故f(j)和f(i)k4为之前部分相等。a[i]+= x,等于data[i]+=x,按如下方式迭代i: i +g(x)。如果f(j)>f(i),说明i的最低位1后面有1,根据性质四,无法如何j都不会大于i。求a[i]的值:即区间a[i…原创 2025-03-10 07:00:00 · 2759 阅读 · 69 评论 -
二元一次方程的整数解、逆元及有理数求模
解ax+by=gcd(a,b) a,b无需互质,可以全部或部分为负数。原创 2024-12-18 12:02:46 · 2657 阅读 · 100 评论 -
【数学归纳法 组合数学】容斥原理
要计算几个集合并集的大小,我们要先将所有单个集合的大小计算出来,然后减去所有两个集合相交的部分,再加回所有三个集合相交的部分,再减去所有四个集合相交的部分,依此类推,一直计算到所有集合相交的部分。原创 2024-04-23 17:00:00 · 1676 阅读 · 0 评论 -
C++数学
哈曼顿距离:max(x1-x2,x2-x1)+max(y1-y2,y2-y1) = max(x1-x2+y1-y2,x1-x2+y2-y1,x2-x1+y1-y2,x2-x1+y2-y1)利用f(x,y)=(x+y,x-y)将点1(x1,y1)点2(x2,y2)转成点3(x3,y3)和点4(x4,y4)后,点1到点2的哈曼顿距离等于点3到点4的切比雪夫距离。切比雪夫距离:max(|x1-x2|,|y1-y2|)。= max(|x3-x4|,|y3-y4|)即点3到点4的切比雪夫距离。三维:(x,y,z)原创 2024-11-11 07:00:00 · 6180 阅读 · 114 评论 -
C++贪心
贪心算法(Greedy Algorithm)是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法策略。贪心算法的正确性必须证明。常见的证明方法有五种:一,反证法。二,数学归纳法。三,决策包容性。 四,扩展决策范围。五,临项交换。原创 2024-10-21 07:00:00 · 2867 阅读 · 107 评论 -
C++队列、双向队列、单调队列
队列(Queue)是一种基本的线性数据结构,它遵循先进先出(First In First Out, FIFO)的原则。这意味着最先被添加到队列中的元素将会是最先被移除的。和生活中,无人插队的队列一样。队列内部实现可能是连续空间,也可能是多段空间。原创 2024-09-30 07:00:00 · 3244 阅读 · 105 评论 -
C++堆(优先队列)priority_queue
堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆(大根堆);每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆(小根堆)。从堆的概念可知,堆是一棵完全二叉树,因此可以使用层序的规则采用顺序的方式来高效存储。完全二叉树,我的理解:任何节点的子节点只有以下三种情况:一,没有孩子。二,有两个孩子。三,只有左孩子。不会出现只有右孩子,没有左孩子的情况。根节点的编号1,根节点的左孩子编号2,根节点的右孩子编号3。2的孩子编号为:4,5。3的孩子编号:6,7。原创 2024-09-24 07:00:00 · 1279 阅读 · 0 评论 -
C++离线查询
离线算法( offline algorithms),离线计算就是在计算开始前已知所有输入数据,输入数据不会产生变化,且在解决一个问题后就要立即得出结果的前提下进行的计算。通俗的说:离线查询:问完所有问题后,依次回答。可以按某个查询值排序,这样方便处理。**注意**:要记录排序前,排序后的对应关系。比如:对查询的下标排序,不对查询排序。在线查询:每问一个问题,就回答。原创 2024-09-23 07:00:00 · 4133 阅读 · 121 评论 -
C++栈(Stack)
栈(Stack)是只允许在一端进行插入或者删除操作的线性表。它的操作特性可以概括为——后进先出(Last In First Out,LIFO)。栈顶(Top)——线性表允许进行插入删除的一端;栈底(Bottom)——线性表不允许进行插入删除的一端;原创 2024-06-13 07:00:00 · 2491 阅读 · 62 评论 -
C++前后缀分解
分治法的一种,将数组和字符串,拆分成前缀和后缀。字符串(数组)的前缀是字符串的前i个元素:s.substr(0,i-1),即s[0] $\dots$ s[i-1]。同理后缀就是字符串s的后几个元素(字符)。不失一般型,我们以字符串s=“abcde"为例,s有5种拆分方法:原创 2024-09-16 07:00:00 · 2135 阅读 · 115 评论 -
割点原理及封装好的割点类
**性质一**: 搜索树上的两点连通,则对应的图一定连通。因为:搜索树有的边,对应的图都有。**性质二**:搜索树上,假定一个节点n1有m个子节点,则删除n1和相关边后,有1+m个连通区域。各子节点各一个连通区域,其它节点一个连通区域(简称根子树)。根据性质一,对应的图最多1+m个连通区域。**性质三**:dfs(c1)前,c1到c10的某条路径全部是未访问节点,则dfs(c1)时一定会访问c10。令在这条路径上:c1的后继点是c2,c2是c3,c3是c4 $\cdots$第一次处理c1时,c1处理原创 2024-03-11 07:00:00 · 3390 阅读 · 46 评论 -
C++图论
连通图(可能有环)的层次。选取任意节点root,各节点到root的最短距离就是各节点的层次。显然root的层次是0。原创 2024-04-11 07:00:00 · 2569 阅读 · 86 评论 -
组合数学汇总
阶乘、排列、组合、帕斯卡法则、容斥原理原创 2024-05-09 07:00:00 · 2093 阅读 · 35 评论 -
VS2019打开《喜缺全书算法册》附带代码的方法兼述单元测试
使用方法一:修改某个封装类,然后运行所有测试用例。看是否有测试用例,没通过。调试没有通过的测试用例。在改测试用例上,单击鼠标右键,在右键菜单中选择“调试”。使用方法二:修改某题的源码,然后运行此类的测试用例。使用方法三:输出日志。Microsoft::VisualStudio::CppUnitTestFramework::Logger::WriteMessage("d"); 选中此测试用例才会显示结果。原创 2024-07-28 07:00:00 · 4664 阅读 · 67 评论 -
C++差分数组
差分数组(Difference Array)是一种巧妙的数据结构,常用于处理序列的各种动态修改问题,尤其是具有前后元素关联的操作。令数据数组是data,diff[i]记录data[i]-data[i-1],则data[i] = diff[0...i]之和。差分数组的优点:常数时间进行区间修改。原创 2024-06-20 07:00:00 · 2459 阅读 · 145 评论 -
【数据结构】前缀树(字典树)汇总
{“a”,“abc”,“bac”,“bbc”,“ca” }的字典树如下图:最主用的应用:一,字符串编码。二,位运算。原创 2024-06-10 07:00:00 · 1514 阅读 · 2 评论 -
C++记忆化搜索
记忆化搜索(Memoization Search):是一种通过存储已经遍历过的状态信息,从而避免对同一状态重复遍历的搜索算法。记忆化搜索是动态规划的一种实现方式。在记忆化搜索中,当算法需要计算某个子问题的结果时,它首先检查是否已经计算过该问题。如果已经计算过,则直接返回已经存储的结果;否则,计算该问题,并将结果存储下来以备将来使用。原创 2024-06-06 07:00:00 · 2298 阅读 · 2 评论 -
【排列组合 隔板法 容斥原理】放球问题
放球问题是一类很有意思的排列组合问题。通俗来说,就是把n个小球放到m个盒子里,问有几种放法。具体可以从3个维度,每个维度2种情况,共8种情况:维度一:小球是否相同。维度二: 盒子是否相同。维度三: 是否容许盒子为空。原创 2024-06-03 07:00:00 · 2751 阅读 · 0 评论 -
【动态规划 组合数学 放球问题】2338. 统计理想数组的数目|2615
给你两个整数 n 和 maxValue ,用于描述一个 理想数组 。对于下标从 0 开始、长度为 n 的整数数组 arr ,如果满足以下条件,则认为该数组是一个 理想数组 :每个 arr[i] 都是从 1 到 maxValue 范围内的一个值,其中 0原创 2024-05-31 07:00:00 · 1069 阅读 · 5 评论 -
Z 函数(扩展 KMP)
约定:字符串下标以 0 为起点。定义对于一个长度为 n 的字符串 s,定义函数 z[i] 表示 s 和 s[i,n-1](即以 s[i] 开头的后缀)的最长公共前缀(LCP)的长度,则 z 被称为 s 的 Z 函数。特别地,z[0] = 0。国外一般将计算该数组的算法称为 Z Algorithm,而国内则称其为 扩展 KMP。这篇文章介绍在 O(n) 时间复杂度内计算 Z 函数的算法以及其各种应用。原创 2024-05-30 17:00:00 · 2695 阅读 · 0 评论 -
【可复用性、可测试性、可理解性】算法与数据结构按汇总
本文的算法汇总,包括但不限于动态规划、回溯、贪心、分支、图论、组合数学、数量等。原创 2024-05-23 08:28:25 · 3042 阅读 · 0 评论 -
【图论 深度优先搜索 反证法 分类讨论】树的直径
有根树的深度:根到叶子节点的距离。有根数的搞定:叶子到根节点的距离。两者本质是一样,习惯不同而已。树的直径——就是树中距离最大的两点的距离。 以任意节点为根的最大深度。原创 2024-05-21 17:00:00 · 1079 阅读 · 1 评论 -
C++回溯
我对回溯的定义是不定层循环,此定义并不规范,但容易理解。回溯基本上用深度优先搜索实现,暂未发现反例。而深度优先搜索绝大部分是用递归实现。原创 2024-05-20 07:00:00 · 2512 阅读 · 39 评论 -
C++深度优先搜索DFS
扩展新的节点,不断递归执行这个过程,直到某个节点不能再扩展下一个节点为止。此时,则返回上一个节点重新寻找一个新的扩展节点。如此搜索下去,直到找到目标节点,或者搜索完所有节点为止。原创 2024-05-16 07:00:00 · 1294 阅读 · 41 评论 -
【C++数轮】数论、质数、最大公约数、菲蜀定理
数论、质数、最大公约数、菲蜀定理原创 2024-05-13 08:32:32 · 1332 阅读 · 0 评论 -
C++位运算、状态压缩、枚举子集汇总
位运算的结合性都是从左到右。优先级低的先运算。|优先级|位运算符|说明||-|-|-|7 |> |位左移/位右移10|& |按位与11|^|按位异或12 | |按位或原创 2024-04-29 08:31:26 · 2832 阅读 · 32 评论 -
C++背包问题
有n件物品,体积分别是v[i],价值分别是w[i],有个包的容积是bv。如何选择物品使得,在总体积不超过vb的前提下,让总价值最大。原创 2024-04-25 07:00:00 · 4145 阅读 · 127 评论 -
【数学归纳法 反证法】菲蜀定理
裴蜀定理(或贝祖定理,Bézout's identity)得名于法国数学家艾蒂安·裴蜀,说明了对任何整数a、b和它们的最大公约 数d,关于未知数x和y的线性不定方程(称为裴蜀等式):若a,b是整数,且(a,b)=d,那么对于任意的整数x,y,ax+by都一定是d的倍数,特别地,一定存在整数x,y,使ax+by=d成立。它的一个重要推论是:a,b互质的充要条件是存在整数x,y使ax+by=1.原创 2024-04-23 07:00:00 · 1041 阅读 · 9 评论 -
【位运算】3097. 或值至少为 K 的最短子数组 II
给你一个 非负 整数数组 nums 和一个整数 k 。如果一个数组中所有元素的按位或运算 OR 的值 至少 为 k ,那么我们称这个数组是 特别的 。请你返回 nums 中 最短特别非空 子数组的长度,如果特别子数组不存在,那么返回 -1 。原创 2024-04-15 17:00:00 · 1795 阅读 · 15 评论 -
【图论】 【割点】 【双连通分类】LCP 54. 夺回据点
魔物了占领若干据点,这些据点被若干条道路相连接,roads[i] = [x, y] 表示编号 x、y 的两个据点通过一条道路连接。现在勇者要将按照以下原则将这些据点逐一夺回:在开始的时候,勇者可以花费资源先夺回一些据点,初始夺回第 j 个据点所需消耗的资源数量为 cost[j]接下来,勇者在不消耗资源情况下,每次可以夺回一个和「已夺回据点」相连接的魔物据点,并对其进行夺回注:为了防止魔物暴动,勇者在每一次夺回据点后(包括花费资源夺回据点后),需要保证剩余的所有魔物据点之间是相连通的(不经过「已夺回据原创 2024-03-11 12:27:05 · 1362 阅读 · 12 评论
分享