PAT笔记
这里记录了一下常用的保研机试,剑指offer和PAT题目分类解析,主要用来快速回顾和复习相关模板,以及数据结构相关的知识点。
字符串
- 在c++中处理字符串类型的题目时,我们一般使用
string
,有时候我们也使用char[]
方式进行操作。 HH:MM:SS
可以直接通过字符串字典序排序- 输入一个包含空格的字符串需要使用
getline(cin,s1)
STL
vector<int>
本省具备有字典序比较的方法,重载了< == >
的运算符号vector<int>::iterator iter=find(vec.begin(),vec.end(),target); if(iter==vec.end()) cout << "Not found" << endl;
高精度
int
的范围$-2 \times 10^9 - 2 \times 10^9$long long
$-9 \times 10^{18} - 9 \times 10^{18}$- 用
vector
按位存储进制转换
- 其他进制化成10进制,采用秦九韶算法
|
- 十进制转其他进制的方法,使用带余除法
|
判断质数
|
手写堆排序
堆是一个完全二叉树的结构,分为小根堆和大根堆两种结构。
- 小根堆的递归定义:小根堆的每个节点都小于他的左右孩子节点的值,树的根节点为最小值。
- 大根堆的递归定义:大根堆的每个节点都大于他的左右孩子节点的值,树的根节点为最大值。
在STL当中可以使用prioirty_queue
来轻松实现大根堆和小根堆,但是只能实现前3个功能,有时候我们不得不自己实现一个手写的堆,同时这样也能让我们更理解堆排序的过程。
在AcWing基础课当中有两道经典例题,AcWing 839. 模拟堆(这个复杂一点),AcWing 838. 堆排序
这里给出堆排序的模板级代码
|
STL写法:priority_queue
默认是大根堆,less<int>
是对第一个参数的比较类,表示数字大的优先级越大,而greater<int>
表示数字小的优先级越大,可以实现结构体运算符重载。
首先要引入头文件:#include<queue>
大根堆:
|
小根堆:
|
树
树是一种特殊的数据结构形式,在做题的过程当中,根据我的经验当题目需要使用树结构的时候主要有以下几种模式。
- 二叉树形式,在二叉树模型下,我们可以根据题目建立出静态的树形结构,构建每个节点左右孩子索引表来建立树的结构同时实现对树的遍历。如果已知或可以求得节点之间的关系,可以通过节点的度数或者访问标记找到根节点。,当然也是可以通过邻接表的方式创建二叉树。
- 多叉树形式,多叉树形式其实又类似于无向连通图的概念,常通过创建邻接表或者临接矩阵的方式建立树,并实现进行树的遍历,也是可以根据节点关系求出根节点的。注意在临接表当中,边的数量一般大于节点数量的两倍即我们需要开票邻接表的边数空间为$M = 2 \times N + d$
- 森林,多连通块的方式,这种也是利用无向图的方式,以邻接表或者临接矩阵的方式构建树的结构,同时我们可以利用并查集的方式得到当前无向图中含有的连通块数量并找到根节点。
二叉树左右孩子索引表模型
|
二叉树的遍历过程(以先序遍历为例子)
|
临接表模型
|
临接表遍历过程方法1
|
临接表遍历过程方法2
|
树的深度
临接表模型:AcWing1498. 最深的根
|
二叉树模型:剑指 Offer 55 - I. 二叉树的深度
|
多叉树模型(该题也是求叶子节点个数的经典写法):AcWing 1476. 数叶子结点
|
二叉搜索树
二叉搜索树 (BST) 递归定义为具有以下属性的二叉树:
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值
- 若它的右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值
- 它的左、右子树也分别为二叉搜索树
二叉搜索树的中序遍历一定是有序的
完全二叉树
完全二叉树 (CBT) 定义为除最深层外的其他层的结点数都达到最大个数,最深层的所有结点都连续集中在最左边的二叉树。
构造完全二叉树的方法,可以直接开辟一个一维数组利用左右孩子与根节点的下标映射关系。如果通过中序遍历的方式以单调递增的方式来赋值则构造出了一颗完全二叉搜索树。
完全二叉树的赋值填充和构造过程(这里我们以中序遍历为例子):
例题:AcWing 1550. 完全二叉搜索树
|
完全二叉树的节点个数规律:
- 具有n个结点的完全二叉树的深度为$\lfloor log_2{n} \rfloor+ 1$
- 完全二叉树如果为满二叉树,且深度为$k$则总节点个数为$2^{k}-1$
- 完全二叉树的第$i(i \geq 1)$层的节点数最大值为$2^{i-1}$
- 完全二叉树最后一层按从左到右的顺序进行编号,上面的层数皆为节点数的最大值,因此不会出现左子树为空,右子树存在的节点
- 根据完全二叉树的结构可知:完全二叉树度为1的节点只能为1或者0,则有当节点总数为$n$时,如果$n$为奇数,则$n_0 = (n+1)/2$,如果$n$为偶数,则$n_0 = n / 2$
关于最后一条性质的一些拓展
二叉树的重要性质:在任意一棵二叉树中,若叶子结点的个数为$n_0$,度为2的结点数为$n_2$,则$n_0=n_2+1$
证明:
假设该二叉树总共有$n$个结点$(n=n_0+n_1+n_2)$,则该二叉树总共会有$n-1$条边,度为2的结点会延伸出两条边,度为1的结点会延伸出1条边。
则有$n - 1 = n_0+n_1+n_2- 1= 2 \times n_2 + n_1$
联立两式得到:$n_0=n_2+1$
拓展到完全二叉树,因为完全二叉树度为1的节点只有0个或者1个。即$n_1 = 0 或 1$
则节点总数$n=n_0+n_1+n_2 = 2 *n_0 + n_1 - 1$
由于节点个数必须为整数,因此可以得到以下结论:
当$n$为奇数时,必须使得$n_1=0$,则$n_0=(n + 1) / 2,n_2=n_0-1=(n + 1) / 2-1$
当$n$为偶数时,必须使得$n_1=1$,则$n_0=n / 2,n_2=n_0-1=n /2 -1$
例题(递归解法):leetcode 完全二叉树的节点个数
|
完全二叉树
二叉平衡树
AVL树
- AVL树是一种自平衡二叉搜索树。
- 在AVL树中,任何节点的两个子树的高度最多相差 1 个。
- 如果某个时间,某节点的两个子树之间的高度差超过 1,则将通过树旋转进行重新平衡以恢复此属性。
- AVL本质上还是维护一个二叉搜索树,所以不管如果旋转,其中序遍历依旧是不变的。
旋转法则:
AVL插入分为一下几种情况:
- LL型:新节点的插入位置在A的左孩子的左子树上,则右旋A
- RR型:新节点的插入位置在A的右孩子的右子树上,则左旋A
- LR型:新节点的插入位置在A的左孩子的右子树上,则左旋B,右旋A
- RL型:新节点的插入位置在A的右孩子的左子树上,则右旋B,左旋A
红黑树
数据结构中有一类平衡的二叉搜索树,称为红黑树。
它具有以下 5 个属性:
- 节点是红色或黑色。
- 根节点是黑色。
- 所有叶子都是黑色。(叶子是 NULL节点)
- 每个红色节点的两个子节点都是黑色。
- 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
图论相关
并查集
经典例题:AcWing 836. 合并集合
|
dijstra算法
- 临接矩阵形式,适用于点的数量$N < 1000$的情形,朴素算法即可解决
- 邻接表形式,当$N>10000$,需要添加堆优化
一般来说堆优化版本的考试用的不多,这里就只介绍了朴素版本。
Dijkstra求最短路 I
|
最小生成树Prime
|
最小生成树Kruskal
|
哈密顿图
- 通过图中所有顶点一次且仅一次的通路称为哈密顿通路。
- 通过图中所有顶点一次且仅一次的回路称为哈密顿回路。
- 具有哈密顿回路的图称为哈密顿图。
- 具有哈密顿通路而不具有哈密顿回路的图称为半哈密顿图
欧拉图
- 通过图中所有边恰好一次且行遍所有顶点的通路称为欧拉通路。
- 通过图中所有边恰好一次且行遍所有顶点的回路称为欧拉回路。
- 具有欧拉回路的无向图或有向图称为欧拉图。
- 具有欧拉通路但不具有欧拉回路的无向图或有向图称为半欧拉图。
- 如果一个连通图的所有顶点的度数都为偶数,那么这个连通图具有欧拉回路,且这个图被称为欧拉图。
- 如果一个连通图中有两个顶点的度数为奇数,其他顶点的度数为偶数,那么所有欧拉路径都从其中一个度数为奇数的顶点开始,并在另一个度数为奇数的顶点结束。
数学
gcd
|
1的个数(数位dp)
ACWing1533.1的个数
剑指 Offer 43. 1~n 整数中 1 出现的次数
给定一个数字 N,请你计算 1∼N 中一共出现了多少个数字 1。
例如,N=12 时,一共出现了 5 个数字 1,分别出现在 1,10,11,12 中。
解题思路:相关视频链接
|