
算法基础
文章平均质量分 95
算法基础
软件架构师何志丹
我的源码、视频、博文、电子书可复用性、可理解性、可测试性皆强。优于工作,劣于竞赛。源码:https://gitcode.com/invite/link/a07392368f3a4ae295c0
展开
-
【数学 线性代数】差分约束
x系列是变量,y系列是常量,差分系统由若干如下不等式组成。x1-x2 <= y1 x2-x3 <= y2 $\cdots$原创 2025-03-17 07:00:00 · 3125 阅读 · 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 · 2335 阅读 · 69 评论 -
二元一次方程的整数解、逆元及有理数求模
解ax+by=gcd(a,b) a,b无需互质,可以全部或部分为负数。原创 2024-12-18 12:02:46 · 2463 阅读 · 100 评论 -
【数学归纳法 组合数学】容斥原理
要计算几个集合并集的大小,我们要先将所有单个集合的大小计算出来,然后减去所有两个集合相交的部分,再加回所有三个集合相交的部分,再减去所有四个集合相交的部分,依此类推,一直计算到所有集合相交的部分。原创 2024-04-23 17:00:00 · 1429 阅读 · 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 · 5905 阅读 · 114 评论 -
C++贪心
贪心算法(Greedy Algorithm)是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法策略。贪心算法的正确性必须证明。常见的证明方法有五种:一,反证法。二,数学归纳法。三,决策包容性。 四,扩展决策范围。五,临项交换。原创 2024-10-21 07:00:00 · 2571 阅读 · 107 评论 -
C++队列、双向队列
队列(Queue)是一种基本的线性数据结构,它遵循先进先出(First In First Out, FIFO)的原则。这意味着最先被添加到队列中的元素将会是最先被移除的。和生活中,无人插队的队列一样。队列内部实现可能是连续空间,也可能是多段空间。原创 2024-09-30 07:00:00 · 3048 阅读 · 105 评论 -
C++堆(优先队列)priority_queue
堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆(大根堆);每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆(小根堆)。从堆的概念可知,堆是一棵完全二叉树,因此可以使用层序的规则采用顺序的方式来高效存储。完全二叉树,我的理解:任何节点的子节点只有以下三种情况:一,没有孩子。二,有两个孩子。三,只有左孩子。不会出现只有右孩子,没有左孩子的情况。根节点的编号1,根节点的左孩子编号2,根节点的右孩子编号3。2的孩子编号为:4,5。3的孩子编号:6,7。原创 2024-09-24 07:00:00 · 909 阅读 · 0 评论 -
C++离线查询
离线算法( offline algorithms),离线计算就是在计算开始前已知所有输入数据,输入数据不会产生变化,且在解决一个问题后就要立即得出结果的前提下进行的计算。通俗的说:离线查询:问完所有问题后,依次回答。可以按某个查询值排序,这样方便处理。**注意**:要记录排序前,排序后的对应关系。比如:对查询的下标排序,不对查询排序。在线查询:每问一个问题,就回答。原创 2024-09-23 07:00:00 · 3872 阅读 · 121 评论 -
C++栈(Stack)
栈(Stack)是只允许在一端进行插入或者删除操作的线性表。它的操作特性可以概括为——后进先出(Last In First Out,LIFO)。栈顶(Top)——线性表允许进行插入删除的一端;栈底(Bottom)——线性表不允许进行插入删除的一端;原创 2024-06-13 07:00:00 · 2353 阅读 · 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 · 1887 阅读 · 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 · 3323 阅读 · 46 评论 -
C++图论
连通图(可能有环)的层次。选取任意节点root,各节点到root的最短距离就是各节点的层次。显然root的层次是0。原创 2024-04-11 07:00:00 · 2289 阅读 · 86 评论 -
组合数学汇总
阶乘、排列、组合、帕斯卡法则、容斥原理原创 2024-05-09 07:00:00 · 1959 阅读 · 35 评论 -
VS2019打开《喜缺全书算法册》附带代码的方法兼述单元测试
使用方法一:修改某个封装类,然后运行所有测试用例。看是否有测试用例,没通过。调试没有通过的测试用例。在改测试用例上,单击鼠标右键,在右键菜单中选择“调试”。使用方法二:修改某题的源码,然后运行此类的测试用例。使用方法三:输出日志。Microsoft::VisualStudio::CppUnitTestFramework::Logger::WriteMessage("d"); 选中此测试用例才会显示结果。原创 2024-07-28 07:00:00 · 4103 阅读 · 61 评论 -
C++差分数组
差分数组(Difference Array)是一种巧妙的数据结构,常用于处理序列的各种动态修改问题,尤其是具有前后元素关联的操作。令数据数组是data,diff[i]记录data[i]-data[i-1],则data[i] = diff[0...i]之和。差分数组的优点:常数时间进行区间修改。原创 2024-06-20 07:00:00 · 2216 阅读 · 145 评论 -
【数据结构】前缀树(字典树)汇总
{“a”,“abc”,“bac”,“bbc”,“ca” }的字典树如下图:最主用的应用:一,字符串编码。二,位运算。原创 2024-06-10 07:00:00 · 1455 阅读 · 2 评论 -
C++记忆化搜索
记忆化搜索(Memoization Search):是一种通过存储已经遍历过的状态信息,从而避免对同一状态重复遍历的搜索算法。记忆化搜索是动态规划的一种实现方式。在记忆化搜索中,当算法需要计算某个子问题的结果时,它首先检查是否已经计算过该问题。如果已经计算过,则直接返回已经存储的结果;否则,计算该问题,并将结果存储下来以备将来使用。原创 2024-06-06 07:00:00 · 2007 阅读 · 2 评论 -
【排列组合 隔板法 容斥原理】放球问题
放球问题是一类很有意思的排列组合问题。通俗来说,就是把n个小球放到m个盒子里,问有几种放法。具体可以从3个维度,每个维度2种情况,共8种情况:维度一:小球是否相同。维度二: 盒子是否相同。维度三: 是否容许盒子为空。原创 2024-06-03 07:00:00 · 2077 阅读 · 0 评论 -
【动态规划 组合数学 放球问题】2338. 统计理想数组的数目|2615
给你两个整数 n 和 maxValue ,用于描述一个 理想数组 。对于下标从 0 开始、长度为 n 的整数数组 arr ,如果满足以下条件,则认为该数组是一个 理想数组 :每个 arr[i] 都是从 1 到 maxValue 范围内的一个值,其中 0原创 2024-05-31 07:00:00 · 987 阅读 · 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 · 2320 阅读 · 0 评论 -
【可复用性、可测试性、可理解性】算法与数据结构按汇总
本文的算法汇总,包括但不限于动态规划、回溯、贪心、分支、图论、组合数学、数量等。原创 2024-05-23 08:28:25 · 2680 阅读 · 0 评论 -
【图论 深度优先搜索 反证法 分类讨论】树的直径
有根树的深度:根到叶子节点的距离。有根数的搞定:叶子到根节点的距离。两者本质是一样,习惯不同而已。树的直径——就是树中距离最大的两点的距离。 以任意节点为根的最大深度。原创 2024-05-21 17:00:00 · 995 阅读 · 1 评论 -
C++回溯
我对回溯的定义是不定层循环,此定义并不规范,但容易理解。回溯基本上用深度优先搜索实现,暂未发现反例。而深度优先搜索绝大部分是用递归实现。原创 2024-05-20 07:00:00 · 2421 阅读 · 39 评论 -
C++深度优先搜索DFS
扩展新的节点,不断递归执行这个过程,直到某个节点不能再扩展下一个节点为止。此时,则返回上一个节点重新寻找一个新的扩展节点。如此搜索下去,直到找到目标节点,或者搜索完所有节点为止。原创 2024-05-16 07:00:00 · 1174 阅读 · 41 评论 -
【C++数轮】数论、质数、最大公约数、菲蜀定理
数论、质数、最大公约数、菲蜀定理原创 2024-05-13 08:32:32 · 1163 阅读 · 0 评论 -
C++位运算、状态压缩、枚举子集汇总
位运算的结合性都是从左到右。优先级低的先运算。|优先级|位运算符|说明||-|-|-|7 |> |位左移/位右移10|& |按位与11|^|按位异或12 | |按位或原创 2024-04-29 08:31:26 · 2530 阅读 · 32 评论 -
C++背包问题
有n件物品,体积分别是v[i],价值分别是w[i],有个包的容积是bv。如何选择物品使得,在总体积不超过vb的前提下,让总价值最大。原创 2024-04-25 07:00:00 · 4004 阅读 · 125 评论 -
【数学归纳法 反证法】菲蜀定理
裴蜀定理(或贝祖定理,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 · 846 阅读 · 9 评论 -
【位运算】3097. 或值至少为 K 的最短子数组 II
给你一个 非负 整数数组 nums 和一个整数 k 。如果一个数组中所有元素的按位或运算 OR 的值 至少 为 k ,那么我们称这个数组是 特别的 。请你返回 nums 中 最短特别非空 子数组的长度,如果特别子数组不存在,那么返回 -1 。原创 2024-04-15 17:00:00 · 1756 阅读 · 15 评论 -
【图论】 【割点】 【双连通分类】LCP 54. 夺回据点
魔物了占领若干据点,这些据点被若干条道路相连接,roads[i] = [x, y] 表示编号 x、y 的两个据点通过一条道路连接。现在勇者要将按照以下原则将这些据点逐一夺回:在开始的时候,勇者可以花费资源先夺回一些据点,初始夺回第 j 个据点所需消耗的资源数量为 cost[j]接下来,勇者在不消耗资源情况下,每次可以夺回一个和「已夺回据点」相连接的魔物据点,并对其进行夺回注:为了防止魔物暴动,勇者在每一次夺回据点后(包括花费资源夺回据点后),需要保证剩余的所有魔物据点之间是相连通的(不经过「已夺回据原创 2024-03-11 12:27:05 · 1312 阅读 · 12 评论 -
动态规划的时间复杂度优化
优化动态规划的时间复杂度,主要有如下几种:原创 2024-02-26 07:00:00 · 5993 阅读 · 164 评论 -
【深度优先搜索】【树】【有向图】【推荐】685. 冗余连接 II
在本问题中,有根树指满足以下条件的 有向 图。该树只有一个根节点,所有其他节点都是该根节点的后继。该树除了根节点之外的每一个节点都有且只有一个父节点,而根节点没有父节点。输入一个有向图,该图由一个有着 n 个节点(节点值不重复,从 1 到 n)的树及一条附加的有向边构成。附加的边包含在 1 到 n 中的两个不同顶点间,这条附加的边不属于树中已存在的边。结果图是一个以边组成的二维数组 edges 。 每个元素是一对 [ui, vi],用以表示 有向 图中连接顶点 ui 和顶点 vi 的边,其中 ui 是原创 2024-02-19 07:00:00 · 2047 阅读 · 85 评论 -
动态规划(Dynamic Programming)
动态规划(Dynamic Programming,DP)是运筹学的一个分支,是求解决策过程最优化的过程。每次决策依赖于当前状态,又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划。原创 2024-01-20 17:00:00 · 2748 阅读 · 16 评论 -
矩阵性质、矩阵结合率、矩阵快速幂封装类及测试用例及样例
性质一:单位矩形I−nI-nI−n,n阶方阵,主对角线1,其它0。XI=X,IX=X。下面以AB=C为例。c[r][c] =∑j0n−1arj∗bjc∑j0n−1arj∗bjc])B是单位矩阵时:b[j][c],当j== c时为1,其它为0,故c[r][c]=a[r][c]。A是单位矩阵时:a[r][j],当j==r时为1,其它为0,故c[r][c]=b[r][c]。性质二:AB等于(BA)的转置矩阵,单位矩阵的转置矩阵是本身。原创 2024-01-15 07:00:00 · 1846 阅读 · 168 评论 -
【数位dp】【动态规划】C++算法:233.数字 1 的个数
给定一个整数 n,计算所有小于等于 n 的非负整数中数字 1 出现的个数。原创 2024-01-08 17:00:00 · 1085 阅读 · 3 评论 -
C++算法:滑动窗口与双指针
滑动窗口与双指针:一,定长滑动窗口。二,不定长滑动窗口。二a,最长最数组。二b,最短子数组。二c,统计子数组数量(越长越合法)。二d,统计子数组数量(越短越合法)。二e,恰好子数组数量。原创 2024-01-01 08:42:24 · 1644 阅读 · 4 评论 -
C++单调栈
通过枚举最小(最大)值不重复、不遗漏枚举所有子数组二分查找的进一步优化最小(最大)字典序原创 2023-12-23 17:00:00 · 1938 阅读 · 24 评论 -
【二分查找】自写二分函数的总结
我暂时只发现两种:一,在左闭右开的区间寻找最后一个符合条件的元素,我封装成FindEnd函数。二,在左开右闭的区间寻找第一个符合条件的元素,我封装成FindFirst函数。原创 2023-12-17 17:00:00 · 238 阅读 · 8 评论 -
C++二分查找算法
包括:二分查找的原理,证明,及样例。分四类:自己写二分算法 有序映射 对有序向量二分查找 有序集合原创 2023-11-19 07:00:00 · 2014 阅读 · 0 评论