
算法学习知识点总结
文章平均质量分 61
算法学习知识点
爱编程的大李子
路漫漫其修远兮,吾将上下而求索
展开
-
C++入门:C++数组可以开多大
一个由C/C++编译的程序占用的内存分为以下几个部分栈区(stack):由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。堆区(heap) :一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由转载 2021-05-10 22:11:13 · 1881 阅读 · 0 评论 -
字符串之KMP算法
KMP有什么用KMP主要应用在字符串匹配上。KMP的主要思想是当出现字符串不匹配时,可以知道一部分之前已经匹配的文本内容,可以利用这些信息避免从头再去做匹配了。所以如何记录已经匹配的文本内容,是KMP的重点,也是next数组肩负的重任。...原创 2021-11-25 19:43:51 · 737 阅读 · 4 评论 -
BFS 的使用场景总结:层序遍历、最短路径等问题
DFS 与 BFS 回顾让我们先看看在二叉树上进行 DFS 遍历和 BFS 遍历的代码比较。DFS 遍历使用递归:void dfs(TreeNode root) { if (root == null) { return; } dfs(root.left); dfs(root.right);}BFS 遍历使用队列数据结构:void bfs(TreeNode root) { Queue<TreeNode> queue = new原创 2021-11-07 21:53:05 · 840 阅读 · 0 评论 -
常见的链表问题总结
常见的链表问题总结无法高效获取长度,无法根据偏移快速访问元素,是链表的两个劣势。然而面试的时候经常碰见诸如获取倒数第k个元素,获取中间位置的元素,判断链表是否存在环,判断环的长度等和长度与位置有关的问题。这些问题都可以通过灵活运用双指针来解决。Tips:双指针并不是固定的公式,而是一种思维方式~1.倒数第k个元素的问题设有两个指针 p 和 q,初始时均指向头结点。首先,先让 p 沿着 next 移动 k 次。此时,p 指向第 k+1个结点,q 指向头节点,两个指针的距离为 k 。然后,同时移动 p原创 2021-11-06 09:56:39 · 910 阅读 · 0 评论 -
八大排序算法总结+例题练习(正在不断补充...)
1.插入排序1.基本介绍直接插入排序是最简单的排序方法,每次将一个待排序的记录,插入到已经排好序的数据序列中,得到一个新的长度增1的有序表。如图9-3所示。2.算法步骤:1)设待排序的记录 存储在数组r[1…n]中,可以把第一个记录r[1]看作-一个有序序列。2)依次将[国] (i=2,… n)插入到已经排好序的序列r[1…i-1]中,并保持有序性。例如,利用直接插入排序算法对序列 {12,2,16,30,28,10,16*,20,6,18}进行非递减排序。初始状态,把r[1]看作-一个有序原创 2021-10-09 15:21:35 · 4030 阅读 · 1 评论 -
斐波那契数列的四种解法
题目描述斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从 1963 年起原创 2021-10-06 11:53:12 · 7385 阅读 · 1 评论 -
算法竞赛之查找算法(持续补充...)
顺序查找#include <iostream>using namespace std;#define Maxsize 100int SqSearch(int r[],int n,int x) { //顺序查找 for(int i=0; i<n; i++) //要判断i是否超过范围n if(r[i]==x) //r[i]和x比较 return i;//返回下标 return -1;}int SqSearch2(int r2[],int n,int x) { /原创 2021-10-03 15:13:19 · 174 阅读 · 0 评论 -
算法竞赛入门到进阶之八数码问题模板
/*BFS+Cantor()模板 解决八数码,十六数码问题. */#include<bits/stdc++.h>const int LEN = 362880;using namespace std;struct node{ int state[9]; int dis;};int dir[4][2] = {{-1,0},{1,0},{0,1},{0,-1}};//上下,右左四个方向int visited[LEN] = {0};//每个状态对应的记录, 用于标记是否int原创 2021-10-01 14:10:55 · 201 阅读 · 0 评论 -
C++ 算法竞赛中的结构体自定义排序规则
C++ 有个sort函数,可用于容器的快速排序,默认是从小到大排序,但是如果我们想要从大到小排序,该怎么办呢?一共有三种方式:使用greater()使用一个 自定义比较大小的函数.返回值为true,则代表比较的两个数不进行交换,为false则进行交换. 一句话:符号与规则一致. 想要从小到大的顺序,则为 < 号,想要从大到小的规则,则使用 >.举例:#include<iostream>#include<algorithm>using namespace原创 2021-09-12 18:19:13 · 706 阅读 · 0 评论 -
递归+回溯经典问题----八皇后问题(参考紫书)
问题描述在一个8*8的棋盘上 放置八个皇后 , 使得他们互相不攻击(皇后攻击范围为 同行同列同对角线)方法一 :从64个格子中 选一个子集 , 使得 " 子集 中恰好有八个元素 , 且任意选出的两个格子都不是同一行,同一列同,一对角线" ,这是子集枚举问题 , 然而 , 64个格子的自己有2^64个 , 所需处理数据过大 !方法二:从64个格子中 选八个格子 , 称为组合生成问题 , 根据组合数学 有4.426*10^9中方案 , 虽然比第一种好 , 但是数据量依旧大.原创 2021-06-18 20:15:22 · 287 阅读 · 0 评论 -
紫书之子集生成三种算法
问题描述:给定一个集合,比如{1,2,3,4},要生成所有的子集(不包括空集,也就是2^n-1个集合)注: n个元素集合有2^n个子集.1.增量构造法思路:在已有子集的基础上不断增加新的元素,一直到无法继续添加为止. 另外因为我们排序的是数组的索引,是从小到大的,就不会出现重复的了.参考代码#include<iostream>#include<cstdio>using namespace std;int A[101];//存放集合元素下标的的数组void原创 2021-06-18 17:37:24 · 146 阅读 · 0 评论 -
紫书之枚举排列
1.生成1–n的排列思路:先输出1开头的排列(这一步是递归调用),然后输出以2开头二点排列(也是递归调用),接着以3开头的排列,…最后以n开头的排列.递归函数需要一下参数:已经确定的前缀序列,以便输出需要进行全排列的元素集合,以便依此选做第一个元素。void print_permutation(序列A, 集合S) { if(S.empty()) 输出A; else {按照从小到大的顺序依此考虑S的每个元素v print_permutation(在A的末尾加v后得原创 2021-06-14 17:58:20 · 190 阅读 · 0 评论 -
图之关键路径
引入事件是点,活动是边.1.事件V1的最早发生时间ve[i]2.事件的最迟发生时间vl[i]第一句话是说,最迟事件执行完后,后继的事件要么直接开始,要么可以等会开始,但不能最迟事件正在执行着,后继时间就得开始了,这样是不行的.所以我们可以从已知的汇点从后往前递推,每一次求解弧头的最小值(因为值越小,说明你可以执行时间的时间越长).举例:3.活动ai = <Vj,Vk >的最早发生时间e[i]活动的最早发生时间,只要这个事件可以开始做的时间已到,我们就开始做原创 2021-05-31 23:07:08 · 370 阅读 · 0 评论 -
图之拓扑排序
知识点概述如果中间有环,则环上的每个节点入度必定>=1,则不会进入拓扑序列中.算法步骤邻接表实现#include<iostream> #include<stack>using namespace std;const int MaxVnum=100;//顶点数最大值int indegree[MaxVnum];//入度数组typedef string VexType;//顶点的数据类型为字符型typedef struct AdjNode{ //原创 2021-05-28 18:43:08 · 209 阅读 · 0 评论 -
最短路径——Bellman-Ford算法以及SPFA算法
Dijkstra算法虽然好,但是它不能解决带有负权边(边的权值为负数)的图。接下来介绍一个无论是思想上还是代码实现上都堪称完美的最短路算法:Bellman-Ford。Bellman-Ford算法非常简单,核心代码只有4行,并且可以完美地解决带有负权边的图.思路: 一张有向图,有n个点,m条边,用dis[]数组保存源点到各点的最短距离,可以通过对边进行n-1次的遍历,当其满足dis[v]>dis[u]+w的时候,就对其进行松弛更新,重复n-1次以后就能得到答案,如果n-1次以后还能继续更新,则可以原创 2021-05-22 15:36:56 · 362 阅读 · 0 评论 -
最短路径之Folyd算法
Dijkstra算法是求源点到其它各个顶点的最短路径,如果求解任意两个顶点的最短路径,则需要以每个顶点为源点,重复调用n次Dijkstra算法。完全没必要这么麻烦,下面介绍的Floyd算法可以求解任意两个顶点的最短路径。Floyd 算法又称为插点法,其算法核心是在顶点i到顶点j之间,插入顶点k,看是否能够缩短i和j之间距离(松弛操作)。算法步骤:数据结构。 设置地图的带权邻接矩阵为G.Edge[],即如果从顶点i到顶点j有边,就让G.Edge[jJi]=<i,j>的权值,否则G.Edge原创 2021-05-17 22:06:33 · 1275 阅读 · 0 评论 -
最短路径之Dijkstra算法
引入迪科斯彻提出了著名的单源最短路径求解算法——Dijkstra算法。Dijkstra算法是解决单源最短路径问题的贪心算法,它先求出长度最短的一条路径,再参照该最短路径求出长度次短的一条路径,直到求出从源点到其他各个顶点的最短路径。Dijkstra算法的基本思想是首先假定源点为u,顶点集合V被划分为两部分:集合S和V-S。初始时S中仅含有源点u,其中S中的顶点到源点的最短路径已经确定。集合V-S中所包含的顶点到源点的最短路径的长度待定,称从源点出发只经过S中的点到达V-S中的点的路径为特殊路径,并用原创 2021-05-17 16:08:53 · 5000 阅读 · 0 评论 -
树和二叉树
树1.概述树(Tree)是n(n≥0)个结点的有限集合,当n=0时,为空树;n>0时,为非空树。任意一棵非空树,满足:1)有且仅有一个称之为根的结点;2)除根结点以外的其余结点可分为m(m>0)个互不相交的有限集T1, T2, …, Tm, 其中每一个集合本身又是一棵树,并且称为根的子树(SubTree)。2.树的相关术语● 节点——节点包含数据元素及若干指向子树的分支信息。● 节点的度——节点拥有的子树个数。● 树的度——树中节点的最大度数。● 终端节点——度为0的节点,又称为叶原创 2021-04-25 18:27:49 · 303 阅读 · 0 评论 -
常用排序算法
桶排序#include <stdio.h>//桶排序 int main() { int book[1001],i,j,t,n; for(i=0; i<=1000; i++) book[i]=0; scanf("%d",&n);//输入一个数n,表示接下来有n个数 for(i=1; i<=n; i++) { //循环读入n个数,并进行桶排序 scanf("%d",&t); //把每一个数读到变量t中 book[t]++; //进行计数,对编号为原创 2021-03-24 15:34:28 · 150 阅读 · 0 评论 -
Tarjan算法
在介绍算法之前,首先引入时间戳和追溯点的概念。时间戳: dfn[u]表示 u结点深度优先遍历的序号。追溯点: low[u]表示 u结点或u的子孙能通过非父子边追溯到的dfn最小的结点序号。即回到最早的过去例如,在深度优先搜索中,每个点的时间戳和追溯点求解过程如下。初始时,dfn[u]=low[u], 如果该结点的邻接点未被访问,则一直深度优先遍历,1- -2-3-5-6- -4, 此时4的邻接点1已被访问,且1不是4的父节点,4的父节点是6 (深度优先搜索树上的父结点)。那么4号结点能回到最早的过原创 2021-03-12 16:58:52 · 305 阅读 · 0 评论 -
图的遍历
图的遍历介绍是从图的某一顶点出发,按照某种搜索方式对图中所有顶点访问一次且仅一次。图的遍历可以解决很多搜索问题,在实际中应用非常广泛。图的遍历根据搜索方式的不同,分为广度优先搜索和深度优先搜索。一.深度优先遍历1.1介绍深度优先搜索(Depth First Search, DFS)是最常见的图搜索方法之一。深度优先搜索沿着一条路径一直走下去,无法行进时,回退到刚刚访问的节点,似“不撞南墙不回头,不到黄河不死心”。深度优先遍历是按照深度优先搜索的方式对图进行遍历。深度优先遍历秘籍:后被访问的顶点.原创 2021-02-26 02:25:40 · 10473 阅读 · 7 评论 -
图的存储方式
图的存储一.邻接矩阵邻接矩阵是表示顶点之间关系的矩阵。邻接矩阵存储方法,需要用一个一维数组存储图中顶点的信息,用一个二维数组存储图中顶点之间的邻接关系,存储顶点之间邻接关系的二维数组称为邻接矩阵。1.1邻接矩阵的表示方法(1)无向图的邻接矩阵在无向图中,如果vi到vj有边,则邻接矩阵M[i][j]=M [j][i]=1,否则M [i][j]=0。无向图邻接矩阵的特点如下。1)无向图的邻接矩阵是对称矩阵,并且是唯一的。2)第i行或第i列非零元素的个数正好是第i个顶点的度。(2)有向图的邻原创 2021-02-25 02:04:43 · 667 阅读 · 0 评论 -
详解哈夫曼编码
详解哈夫曼编码 概述通常的编码方法有固定长度和不等长度编码两种。最优编码方案的目的是使总码长度最短。利用字符的使用频率来编码,是不等长编码方法,使得经常使用的字符编码较短,不常使用的字符编码较长。如果采用等长的编码方案,假设所有字符的编码都等长,则表示n个不同的字符需要位。例如三个不同的字符a,b,c,至少需要2位二进制数表示:a:00,b:01,c:10。如果每个字符的使用频率相等的话,固定长度编码是空间效率最高的方法。在这里我们讨论的是不等长度编码.1.设计哈夫曼树不等长编码方法需要解决两个.原创 2021-04-29 14:44:25 · 5078 阅读 · 0 评论 -
万能的搜索之BFS
1.拯救小哈之BFS具体题目描述 点击这里参考代码#include<iostream>#include<queue>using namespace std;struct node { int x; int y; int f; int s;//步数};int NEXT[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };int n, m, startx, starty, p, q, tx, ty, flag;queue<no原创 2021-04-15 10:18:55 · 209 阅读 · 0 评论 -
万能的搜索之DFS
1.全排列输入一个数n,输出1-n的全排列#include<iostream>//DFS 求序列个数using namespace std;int a[10], book[10], n;void dfs(int step){ if (step == n + 1)//前面n个盒子已经拍好. { for (int i = 1; i <= n; i++) { cout << a[i]; } cout << endl; } fo原创 2021-04-15 09:29:37 · 241 阅读 · 0 评论 -
C++常用字符串分割方法
一、用strtok函数进行字符串分割原型: char *strtok(char *str, const char *delim);功能:分解字符串为一组字符串。参数说明:str为要分解的字符串,delim为分隔符字符串。返回值:从str开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。其它:strtok函数线程不安全,可以使用strtok_r替代。示例://借助strtok实现split#include <string.h>#include <stdio.h&转载 2021-04-10 10:01:22 · 3542 阅读 · 0 评论 -
stringstream去除字符串空格的用法
stringstream具有类型转换,字符串拼接,以及去除字符串中间的空格等功能去除字符串中间的空格:把字符串存入stringstream中,就会自动以空格作为分隔符,然后每次从stringstream中获取字符串的一部分,便达到了分割字符串的效果。#include<iostream>#include<sstream>using namespace std;stringstream s;int main() { string s1("hello, world !转载 2021-04-06 21:05:18 · 2385 阅读 · 0 评论 -
C++ 实现beginwith(),endwith()
实现代码#include<iostream>#include<string>using namespace std;int endswith(string s, string sub) { if (s.rfind(sub) == -1) {//排除出现类似s:23 sub:123的情况. return 0; } else { return s.rfind(sub) == (s.length() - sub.length()) ? 1 : 0; }}i原创 2021-03-27 21:55:29 · 1573 阅读 · 0 评论 -
算法竞赛中小知识点总结(不断更新)
int类型的大小:2*10^9Long long 类型:8个字节Double:1.7*10^308Menset()函数:初始化数组 使用时需要包含string.h头文件void *memset(void *str, int c, size_t n)参数• str -- 指向要填充的内存块。• c -- 要被设置的值。该值以 int 形式传递,但是函数在填充内存块时是使用该值的无符号字符形式。• n -- 要被设置为该值的字符数。返回值该值返回一个指向存储区 str 的指..原创 2021-03-15 12:15:50 · 289 阅读 · 0 评论 -
C++中小数的四舍五入
C++中小数的四舍五入介绍下常见的三个可以让小数转换成整数的函数:名称用法floor(m)<=m的最大整数 (向下取整)ceil(m)>=m的最小整数 (向上取整)round(m)m四舍五入对于小数而言,round()函数仅仅保留到整数位,即仅仅对小数点后一位四舍五入.举例round(1.666) =1.000000round(-1.56)=-2.000000如果想要保留小数位数,则可以先乘后除举例#include<iostr原创 2021-03-02 23:26:24 · 4926 阅读 · 2 评论 -
bitset用法
bitset用法介绍bitset大概就是类似于bool数组一样的东西.但是它的每个位置只占1bit(特别特别小)bitset的原理大概是将很多数压成一个,从而节省空间和时间(暴力出奇迹)一般来说bitset会让你的算法复杂度 /32(具体是什么要看计算机)定义与初始化使用bitset类型需#includebitset类型在定义时就需要指定所占的空间,例如bitset<233>bit;bitset类型可以用string和整数初始化(整数转化成对应的二进制)#include&转载 2021-02-25 14:07:27 · 941 阅读 · 0 评论