08 2023 档案
摘要:二分图算法及模板 1. 二分图算法要解决的问题 二分图算法要解决的问题有两个: 1. 用dfs来判断二分图(也称为染色法)。 2. 求二分图的最大匹配。(采用匈牙利算法)。 2. 染色法的基本思想 二分图的定义: 如果某一个图存在如下性质: 1. 可以将节点分为两个集合. 2. 节点之间的边都在集合
阅读全文
摘要:最小生成树算法及模板 1. 最小生成树算法的类型 1. 如果图是稠密图,则用朴素版Prim算法。 2. 如果图是稀疏图,则用堆优化版Prim算法或克鲁斯卡尔算法。 在本博客中,主要讲解朴素Prim算法和克鲁斯卡尔算法。对于堆优化的Prim算法可以用克鲁斯卡尔算法来进行替代。最小生成树问题一般都是无向
阅读全文
摘要:最短路算法及模板 1. 最短路算法概念及解决的问题 所谓最短路问题,实际上就是求从一个节点开始到另外一个节点结束的最短路径。 这里面需要解释一些词汇: 1. 源点<=>起点 2. 汇点<=>终点 3. n表示图内顶点的数量 4. m表示图内边的数量 2. 最短路算法的类型 以上的算法在不同的情况下,
阅读全文
摘要:拓扑排序 1. 拓扑排序的定义 拓扑排序是bfs的一个应用。拓扑排序只针对于有向图,无向图没有拓扑排序。 对于上图的序列我们可以看到如下特点: 对于图中的每一条边(x,y),在拓扑序列中都表现为x在y之前。 如果某一个序列满足以上特点,那么这个序列就称之为拓扑序列。 需要注意的是,并不是每一个图都有
阅读全文
摘要:树与图的遍历 1. 树与图的遍历方式 树与图的遍历方式有两种:深度优先遍历和宽度优先遍历。遍历过程跟之前所讲述的DFS和BFS类似,这里就不再细讲。可以将图的深度优先遍历和宽度优先遍历看做是特殊的深度优先搜索和宽度优先搜索。由于深度优先遍历和宽度优先遍历都会只遍历节点一次,因此时间复杂度是O(n+m
阅读全文
摘要:树与图的存储 1. 树与图的定义 树实际上是一种特殊的图,名为无环连通图。因此,我们只需要了解图的存储方式即可。 图分为:有向图和无向图。 假设,给定两个节点a,b: 1. 在有向图中,a->b 指:a可以走到b,而b不可以走到a。b->a同理。 2. 在无向图中,a-b指:a->b和b->a 因此
阅读全文
摘要:DFS和BFS及模板 1. 定义 DFS俗称深度优先搜索,BFS俗称宽度优先搜索。这两种算法都可以保证遍历图中所有的节点。是一种非常常见的搜索算法。 2. DFS思想 DFS在搜索时,尽量往深去搜索。这种算法的主要思想如下: 1. 选取一个点为起始节点,做好标记代表已经搜索过当前节点。 2. 看看起
阅读全文
摘要:STL专题 1. vector, 变长数组,倍增的思想 size() 返回元素个数 empty() 返回是否为空 clear() 清空 front()/back() push_back()/pop_back() begin()/end() [] 支持比较运算,按字典序 pair<int, int>
阅读全文
摘要:哈希表及模板 1. 哈希表的主要内容 2. 哈希表的定义 哈希表是一种数据结构。主要作用就是将一个范围很大的数据,映射到较小的范围(0-N)(一般来讲N为10的5次方~10的6次方之间)。映射之后,可以进行高效的存储和查找。在哈希表中,我们通常用哈希函数h(x)来完成映射的功能。 因此,如何设计哈希
阅读全文
摘要:堆及模板 1.堆的定义 堆是一颗完全二叉树。所谓完全二叉树就是指除了最后一层之外,其余层的节点都是满的。最后一层节点可以不满,但要依次从左到右排列。需要注意的是,如果最后一层也是满的,就称为满二叉树。 堆除了要满足完全二叉树的特征之外,还要满足以下两点的其中之一: 1. 树中每个节点的值都小于等于左
阅读全文
摘要:并查集及模板 1. 并查集的定义及支持的操作 并查集是一种数据结构,可以高效地(近似为O(1)的时间复杂度)执行下述操作: 1. 将两个集合合并 2. 询问两个元素是否在同一个集合当中。 2. 并查集的类型 并查集根据用途的不同,可以分为三大类型: 1. 朴素并查集(路径压缩) 2. 维护size的
阅读全文
摘要:Trie树及模板 1.Trie树介绍 Trie树又称字典树(单词查找树),是用来高效地存储和查找字符串集合的数据结构。 2. Trie树的操作 我们假设要用Trie树来存储上述的字符串,那么过程如下: 1. 首先,我们需要创建Trie树的根节点。创建之后存储abcdef字符串。首先,从前往后遍历这样
阅读全文
摘要:KMP算法及模板 1.字符串匹配问题 所谓字符串匹配问题就是指:给定一个父串S,有子串p,从父串中找到子串,返回子串在父串的起始位置。若找不到则返回-1。 2.解决上述问题的暴力匹配算法 首先,我们可以利用暴力匹配算法来解决此问题。过程如下: 1. 首先,指针i指向父串S的起始位置 2. 指针j指向
阅读全文
摘要:单调队列及模板 1.单调队列的应用场景 单调队列的应用场景也比较单一,主要围绕着如下问题进行展开: 求滑动窗口中的最大值/最小值。 2.暴力做法分析 我们可以用队列来维护一个滑动窗口。在窗口的滑动过程中,实际上就是在往队列中添加/删除元素的过程。(具体来说,当窗口往右移动时,实际上就是在队尾中添加一
阅读全文
摘要:单调栈及模板 1.单调栈的应用 单调栈的应用是非常有限的,一般只适用于如下的模型: 给定一个序列,对于序列中的每一个数,找到这个数左边/右边离它最近的比它大/小的数是谁?如果找不到,返回-1或其他操作。 如果某一个问题,满足上述的模型,那么我们就可以用单调栈来进行解决。 例如,我们可以通过如上的案例
阅读全文
摘要:队列及模板 1. 队列的定义 队列也是操作受限的线性表,满足先进先出特性。 2. 数组模拟队列 在这里,我们采用数组q来模拟队列,hh代表队头指针,tt代表队尾指针。 队列的常用操作如下: 1. 往队列中插入一个元素 q[++tt] = x; 2. 往队列中弹出一个元素 hh++; 3. 判断队列是
阅读全文
摘要:栈及模板 1.栈的定义 栈可以理解为是操作受限的线性表。栈满足后进先出或先进后出的特性。 在这里,我们采用数组来模拟栈。 2.数组模拟栈 我们可以用数组stk来模拟栈本身,tt代表栈顶的下标。 栈具有如下操作:(注意:不同人实现栈的方法是不同的,但是思想都是相同的。我们用本文中的方法来实现栈) 1.
阅读全文
摘要:链表及模板 1.注意事项 这里讲述的都是用数组来模拟链表。为什么要用数组来模拟链表呢?原因如下: 1. 数组相比于之前所学的动态创建链表,效率更高。 2. 用数组实现更加简洁,操作简单。 因此,这里采用数组来模拟链表,模拟单链表和双链表两种。 2.单链表和双链表的应用 1. 单链表主要用来表示邻接表
阅读全文
摘要:区间合并及模板 1. 区间合并的应用 假设,我们拥有很多区间,我们需要将有交集的区间合并成为一个区间。类似于这样的问题就叫做区间合并问题。请看上图: 区间合并算法就是要尽可能快的完成上述操作。 区间合并算法有时会需要处理一下边界问题,这种情况需要具体问题具体分析。边界问题指的就是当两个区间只有端点重
阅读全文
摘要:离散化及模板 1.离散化的定义及问题引出 在讲解之前,需要注意:我们这里的离散化特指整数离散化,而且是有序(保序)的离散化。这里的有序指的就是原数组A是有序的。保序指的就是原数组A被离散化之后,顺序不发生变化。 在提出上述内容后,我们来阐述一下离散化的定义。假如有这样的一个应用场景:我们需要将10的
阅读全文
摘要:位运算及模板 1.位运算的问题引出及解决方案 关于位运算,有两个常见问题。 1. 给定一个数n,对于n的二进制表示,求其第k位是几。(注意:k是从0开始编号)。 2. 编写一个函数lowbit(x),返回x的二进制表示的最后一位1(这里的x为正数/负数/0均可)。 例如: x = 1010 lowb
阅读全文
摘要:双指针算法及模板 1.第一类双指针算法 第一类双指针算法指的就是: 有两个序列A和B,同时有两个指针i和j。使得i指向其中一个序列,j指向另外一个序列。典型的应用就是在归并排序当中,将两个序列按照某一个规则进行排序时(从小到大或从大到小),使用的就是双指针算法。 2. 第二类双指针算法 第二类双指针
阅读全文
摘要:差分及模板 1.差分的定义及问题引出 给定一个数组:A = a1,a2,...,an 现在构造一个数组B = b1,b2,...,bn,使得: ai = b1+b2+...+bi 那么B就是A的差分。 根据前缀和的定义,我们发现:差分就是前缀和的逆运算。 根据上述定义,引出两个问题: 1. 如何构造
阅读全文
摘要:前缀和及模板 1. 一维前缀和数组定义及问题引出 假设我们拥有原数组:A = a1,a2,a3,...,an 那么,前缀和数组可以定义为:Si = a1+a2+...+ai(即:原数组中前i个数相加所构成的数组) 根据上述的定义,我们可以引出如下问题: 1. 如何求Si? 2. 前缀和数组的作用?
阅读全文
摘要:二分法及模板 1. 种类介绍 二分法按照适用的类型不同,可以分为:整数二分和浮点数二分。不同的类型,模板也各不相同。下面会分情况进行讨论。 2. 二分法的本质 二分法的本质并不在于单调性。如果某个问题具有单调性的性质,那么这个问题一定可以用二分法来解决。如果某个问题利用了二分法来解决,这个问题不一定
阅读全文
摘要:归并排序及模板 1.思想 归并排序也是基于分治法的思想。 1. 确定分界点(一般为中间点mid=(l+r)/2)使得整个数组被划分为left和right区间。 2. 递归排序left和right区间。 3. 归并-合二为一。进而将整个数组排序完成。(注意:在归并的时候,left和right区间都应该
阅读全文
摘要:快速排序及模板 1. 思想 快速排序是基于分治法的思想。首先给定一组数,使用快速排序对其进行排序的话,过程如下: 1. 确定分界点:q[l],q[(l+r)/2],q[r]或者随机都可以 2. 调整区间:如果我们以x为分界点的话,之后我们将区间分为两半。注意,这两半未必长度相等。使得左区间里面的数都
阅读全文
摘要:动态规划-区间DP 1. 区间DP的概念 区间DP,顾名思义就是在一个个的区间上进行DP。 2. 区间DP问题-石子合并 https://www.acwing.com/problem/content/284/ 我们还是从动态规划的两个角度来阐述该问题。 1. 状态表示 本问题,我们可以用二维状态来表
阅读全文
摘要:贪心算法-区间问题 1. 区间选点问题概述及示例 https://www.acwing.com/problem/content/907/ 上图为区间选点问题的示例。 如上图所示:黑色为数轴,蓝色为区间,红色为选择的点。若满足题目要求,最少应选两个点。 2. 区间选点问题步骤 1. 将每个区间按照右端
阅读全文
摘要:贪心算法-Huffman树 1. 哈并果子问题的概述及案例 https://www.acwing.com/problem/content/150/ 上图为本问题的案例。 实际上,本题就是霍夫曼树的应用。关于霍夫曼树的定义,这里就不再赘述。 根据上图,实际上这道题就是在询问:将所有的果子堆进行合并,构
阅读全文