随笔分类 - 数据结构&算法
摘要:我谔谔,数位 dp 几年了还不会,学的都是些奇奇怪怪的写法,导致每次比赛遇到数位 dp 的题要么不会,要么写半天。灵神的数位 dp 模板其实很早就有看过,不过当时不是很理解递归的含义于是放弃了,最近重新来回来看发现还是递归好写,不仅简短而且基本都是一个框架,这就可以大大减少思考量,基本只要遇到数位
阅读全文
摘要:最近接触到一些 DFS 序的题,它可以用来解决一些关于子树的问题。 DFS 序本质就是一棵树在深度优先搜索时访问节点的顺序。比如有下面一棵树,其 DFS 序就是 。 DFS 序有一个很重要的性质,以节点 为
阅读全文
摘要:原文链接: https://www.acwing.com/file_system/file/content/whole/index/content/6489818/ 想必很多同学在接触递归算法的时候都会很困惑,比如归并排序,为什么下面的代码可以将一个序列排好序呢? 今天突然发现,递归过程的本质就是数
阅读全文
摘要:在一个有向图中,每一个点都有唯一的一个出边,那么这个图就是一棵基环树。 因为每个点都有一个出边,因此会一直指向下一个结点。又因为点数有限,因此不可能一直指下去,因此必然存在一个结点会指向之前已经存在过的结点(抽屉原理),所以就一定会形成一个环。又因为这个点只有一条出边,因此它不会再指向其他的结点,环
阅读全文
摘要:前言 之前一直想不明白dfs的时间复杂度是怎么算的,前几天想了下大概想明白了,现在记录一下。 存图方式都是链式前向星或邻接矩阵。主要通过几道经典题目来阐述dfs时间复杂度的计算方法。 是图中结点的个数,是图中边的个数。 深度优先遍历图的每一个结点 时间复杂度为:链式前向星:$O\left
阅读全文
摘要:在KMP算法中我们都知道,当主串与模式串发生失配时,主串的指针不用回溯,而模式串根据最大公共前后缀移动到相应的位置,重新进行匹配,如下图: 由于红色的部分是直接被跳过的,因此有个疑问是,这样子移动会不会跳过恰好与模式串匹配的的位置呢?也就是说在红色的这些部分中,是否存在与模式串完全匹配的某个起始位置
阅读全文
摘要:高精度加法 模板题链接:791. 高精度加法 1 // C = A + B, A >= 0, B >= 0 2 #include <iostream> 3 #include <vector> 4 #include <string> 5 using namespace std; 6 7 vector<
阅读全文
摘要:看了y总的二分,发现与我之前认识的二分完全不同。我之前学的二分查找是最简单的版本,就是在一个排好序的序列里找一个给定的数。而y总讲的二分更多考虑到了边界,就是通过二分找到满足某一条件的边界。现在终于明白为什么说二分的代码很恶心了。 整数二分 首先要知道二分的本质并不是单调有序,也就是说不一定要满足单
阅读全文
摘要:在一个给定的乱序的序列中找到第k个数字,可能会想到先排序,然后输出第k个数。这种方法简单粗暴,时间复杂度为O(nlogn)。 还有一种方法是快速选择,它的思想和快速排序很相似。就是先选择一个数x,然后把这个序列分成左右两边,其中左边的所有的数都<=x,右边的数都>=x。然后比较左边数字的个数left
阅读全文
摘要:之前在学KMP算法时一直理解不了获取next数组的函数是如何实现的,现在大概知道怎么一回事了,记录一下我对获取next数组的理解。 KMP算法实现的原理就不再赘述了,先上KMP代码: 1 void getNext(char *pat, int *next) { 2 next[0] = -1; 3 i
阅读全文
摘要:这里就不再介绍算法的实现原理,直接给出常用的排序算法模板,包括冒泡排序,插入排序,希尔排序,选择排序,堆排序,归并排序,快速排序。这些代码都是我个人常用的模板,代码也比较的简短精炼。若解题有需要,直接套模板即可。 冒泡排序(Bubble Sort) 1 void bubbleSort(int *a,
阅读全文
摘要:写在前面:最近好久没有写blog了,这是因为前段时间在准备计算机转专业的笔试。哎,笔试成绩不容乐观啊,虽然现在还没有公布笔试成绩,但很担心自己没有60分,没有机会去面试。笔试的程序设计题型非常出乎意料,竟然有四道程序设计大题,而且还是在纸上写代码!我非常不习惯,这是因为我几乎都是在IDE码代码,而且
阅读全文
摘要:并查集(union-find disjoint sets)是一种十分精巧和简洁的数据结构,主要用于处理不相交集合的合并问题。正如它的名字一样,并查集的主要的操作有合并(union)与查找(find)。一些算法也会用到并查集,比如求最小生成树的Kruskal算法。下面先通过举例说明并查集的基本概念。
阅读全文
摘要:前言 我们知道,要构造Huffman Tree,每次都要从堆中弹出最小的两个权重的节点,然后把这两个权重的值相加存放到新的节点中,同时让这两个节点分别成为新节点的左右儿子,再把新节点插入到堆中。假设节点个数为n,则重复n-1次后,最后堆中的那个节点就是Huffman Tree的根。 用堆实现当然可以
阅读全文
摘要:遍历二叉树可以用递归的方法去实现,也可以用非递归的方法去实现。递归代码的好处是简洁,直观,最主要的还是递归的代码少,很快就可以写完。但我们知道,递归的调用会用到一个专门的栈,这个栈的深度是有限的,如果递归函数调用的次数很多,超过栈限制的深度,那么程序就会崩溃。这个时候就需要把递归的代码改为非递归了。
阅读全文
摘要:前言 对单链表进行反转是一个很基本的算法。下面将介绍3种不同的单链表反转操作,需要注意的是,我们所讨论的单链表是包含头节点的。 我们的链表节点和main函数以及部分函数的代码如下: 1 #include <cstdio> 2 3 struct LNode { 4 int data; 5 LNode
阅读全文