![](https://img-blog.csdnimg.cn/20210122160416705.jpg?x-oss-process=image/resize,m_fixed,h_224,w_224)
算法及数据结构
文章平均质量分 80
记录算法及数据结构相关内容
gigi怪
这个作者很懒,什么都没留下…
展开
-
关于题型:从序列中找出现次数为k的数(待完成)
文章目录1.序列中的数都出现过偶数次,只有一个数出现过偶数次,求此数1.序列中的数都出现过偶数次,只有一个数出现过偶数次,求此数原创 2021-01-12 15:52:24 · 208 阅读 · 0 评论 -
二叉树相关算法整理(跟新中)
求二叉树的叶子节点数输入1)头结点//递归求叶子节点数int findleafnode(node* head){ if(head==NULL) return 0; if(head->left==NULL&&head->right==NULL) return 1; return findleafnode(head->left)+findleafnode(head->right);}//非递归.原创 2021-01-12 15:51:44 · 135 阅读 · 0 评论 -
--排序算法汇总--
文章目录第三梯队1.1 冒泡排序1.2 选择排序1.3 插入排序1.4 鸡尾酒排序第二梯队2.1 希尔排序2.2 快速排序2.3 归并排序2.4 堆排序第一梯队3.1 计数排序3.2 基数排序3.3 桶排序第三梯队1.1 冒泡排序冒泡排序很形象,即让较大元素想泡泡一样不断往上冒,代码如下。void bubblesort1(int *array,int n){ for(int i = 0;i<n;i++) for(int j = 0;j<n-i-1;j++)原创 2020-11-24 17:07:27 · 111 阅读 · 0 评论 -
关于马拉车算法
马拉车算法用于解决回文串问题,个人经常会忘记其原理,所以在此整理一下。对于回文串,简单说即正着念和反着念是一样的字符串,如abba。用常规的暴力方法,即以一个字符为中心,两边分别外扩,比较每个字符。这种方法需要分奇偶来讨论,即如aba和abba这两种情况。1.马拉车算法首先需要对字符串进行处理,在字符串开头结尾及字符间穿插同一个特殊字符,该字符可以是任何字符,不影响结果。处理后的字符串,不管原字符串长度是奇是偶,都变成了奇,这样就可以以同一种方式处理了。2.这里引入两个变量,分别是R和C。下面将解释原创 2020-10-29 15:19:33 · 414 阅读 · 0 评论 -
关于AVL树及其实现
BST是一种可以实现快速查找的有序数据结构,但其性能受输入元素顺序的影响,比如输入9,8,7,6这样的有序序列,得到的就是一颗极不平衡的二叉树,甚至退化至单链表。为了改善这一点,延伸出了许多以其为基础的二叉树,如红黑树,AVL数,SB树等,他们的区别在于平衡的标准不一,接下来我们探讨下其中的AVL树。AVL树判断平衡的标准很简单,就是该节点左右子树的高度差要不大于1,若是不满足,则进行相应的位置调整。可以列出如下不平衡的四种情况,红色的点即为不满足要求的点。对于RR和LL型,需要分别进行左旋和右旋。而对原创 2020-09-20 16:30:15 · 106 阅读 · 0 评论 -
关于跳表及其实现
对于数组,查询访问十分方便,可以通过下标,偏移量进行随机访问,但其插入删除操作效率不高,还需要进行内容的拷贝。链表很好的弥补了数组增删效率低这一点,通过指针来把零散的空间进行逻辑连接,但是由于链表不支持随机访问,所以需要去遍历,访问效率低,时间复杂度O(n)。跳表对此进行了改进,以空间换取时间,使得时间复杂度可以做到O(logn),相当于链表上实现二分法思想,链表需要有序。那么跳表如何做到这一点的呢,关键就是添加了索引。如下图,最底层的链表即为所有数据存储的区域,而上面的是每一层的索引值。1.查找原创 2020-09-01 20:25:16 · 253 阅读 · 0 评论 -
滑动窗口更新最大最小值
题目暴力方式是把每个子数组中元素遍历,找出最大值然后记录,时间复杂度为O(n*m)。利用滑动窗口结构可以做到O(n)。利用一个双端队列,左右两个值表示窗口两端位置。如上题要求最大值,则要使队列保持递减。窗口右边界向后扩:若队列为空则直接从后插入,若不空,则要保证插入元素的值要小于队列的尾部元素,即要从尾部弹出直至可以插入新元素。窗口左边界向后扩:若队列头所示值为左边界所指的值,则弹出,不是则不操作。vector<int> getmaxarray(vector<int&g.原创 2020-08-30 20:32:23 · 190 阅读 · 0 评论 -
关于Morris遍历
对于树的遍历,无论是递归还是迭代,都是需要额外的空间,由系统记录访问节点压栈,或者自己压栈。而Morris遍历,通过利用节点中的空闲指针,空间复杂度可以做到O(1),且时间复杂度依旧不变O(N).Morris遍历规则:1.若该节点cur有左树,则找到左树最右节点Morrisright(1)若Morrisright的右指针指向NULL,则让其指向cur,cur左移动。(2)若Morris右指针指向cur,则让该右指针指向空,cur右移动。2.若无左树,cur右移。直到cur为空,整棵树遍历完毕,可原创 2020-08-27 17:16:25 · 385 阅读 · 0 评论 -
关于单调栈及其应用
题目有一序列,无重复值。请找出每个位置上左右两边比其小的且距离其最近的值的下标,若无则为-1。如1,2,5,3,4,8,6,9,0。1的左边没有比其小的,右边比起小的最近的是0(8位置上),所以该位置的值[-1,8]。利用单调栈解决单调栈存储数值的下标,下标对应的值在栈中要求是递增的。3位置的数值是3,比栈顶元素小,所以此时要出栈,再一直比较,直到3能够入栈。那么出栈的元素,2 -> 5,其右边最小最近的值就是3 -> 3(哪个元素使他出栈,则就是该元素),其左边最小最近的值就是.原创 2020-08-22 16:06:16 · 125 阅读 · 0 评论 -
KMP查找子串
关于字符串匹配aabaaaaabbaaabaabaabbbaa找出是否有子串aabaab,有则返回开头下标,无则返回-1。1)暴力匹配假设主串长度为n,子串长度m。x为当前主串上的下标,y为当前子串的下标。每次不匹配后,x要往前挪,回到原来位置的下一个位置。y当然也会回到初始位置。那么整个下来的时间复杂度O(n*m)。2)KMP算法首先需要一个next数组,next数组存储的是子串上各位置的最长前后缀长度。如下面的子串aabaab。算法规定0位置值为-1,1位置值为0。那么接下来我.原创 2020-08-18 14:49:37 · 834 阅读 · 0 评论 -
暴力递归到动态规划--马走日,鲍勃的生存概率
题目9*10的棋盘上,马初始在(x,y)上,求k步后到达目标点(endx,endy)的走法数。分析1)递归式2)动规·马当前位置x,y还有剩余步数k为可变量,因此建立三维表格。·可以看出,当k=0,即在最下面这一层时,只有(x,y)等于(enx,eny)的格子上才会标1,即三维表格元素的含义就是在还剩k步的情况下,从坐标(x,y)出发能到达目标点的走法数。因此,需要从k=0层一直往上推,每一层的(x,y)只依赖于其底下一层的(x,y)。分析:鲍勃可以向上下左右移动,必..原创 2020-08-14 15:34:27 · 318 阅读 · 0 评论 -
暴力递归到动态规划--组成额定金额的方法数
对于递归,问题在于其实质为暴力展开,所以会导致重复的操作。通过增设傻缓存记录和动态规划可以优化递归,当元素的依赖数是有限的,比如马跳日,机器人步数等,这时记忆化搜索和动态规划是没多大却别的。但是当有枚举行为时(即不同格子依赖数各不同),就需要动态规划,因为动态规划还具有优化的余地,如下题。题目有一定数目不同面额的货币供选择,每个面额选取数不限,求组成总金额为M的方法数。分析1)递归逻辑比如货币面额放在一个数组,array[2,3,5],表示可供选择的面额有2,3,5。现要求组成1原创 2020-08-14 15:30:17 · 179 阅读 · 0 评论 -
并查集结构,应用及关押囚犯例题
情景a,b,c,d,e,f,6个元素初始时个处于自己的集合,都是孤岛。现在要实现两个操作,一个是issameset,即判断是否在同一个集合;另一个操作是Union,即把两个元素归为同一个集合。如Union(a,b),Union(b,c),那么a和c也是处于同一集合的。要求上述两个操作实现O(1)。·分析初始时假设每个元素都指向自己。当我们实行合并操作,比如Union(a,b),可看成将b的箭头指向a。可以推出,当一个元素不断向上指,只要最终所指的元素相同,那么就认为它们在同一个集合..原创 2020-08-13 16:56:05 · 134 阅读 · 0 评论 -
一致性哈希结构(服务器模型介绍)
经典服务器结构说明:类比之前的文件,现在将文件变成若干台服务器,经过处理来决定将该字符串分配给哪个服务器。那么根据哈希函数性质,每台服务器得到的数据量是平均的(负载也均衡,即每个服务器中高频中频低频的数据量都是整体数量的均分)。当然数据量是尽可能大的情况下。缺点:对于扩容和缩减的数据迁移代价很高,比如数据高峰期,需要增设服务器,数据低峰期需要减少服务器,都需要将所有数据重新分配到各服务器中。·一致性哈希(优化上述问题)比如有一个哈希函数,其所得输出域为0 ~ 2^64 - 1。即把其看做..原创 2020-08-13 16:51:09 · 168 阅读 · 0 评论 -
关于位图与布隆过滤器
情境引入一个文件有100亿个字符串(不重复),每个字符串为64个字节,现在要实现一个黑名单系统,该文件所有字符串加载到该黑名单中,当输入一个字符串时,系统需给出该字符串是否在黑名单上。(类似应用场景:爬虫去重,比如开一定数量的爬虫,需要爬虫爬取不同的内容,即每个爬虫爬之前都要去名单上查询该地址是否爬过,没爬过就爬取并将其记录到名单上。)分析:(1)若单纯用哈希表,那么100*64 = 6400亿,即640G的内存,爆炸。·布隆过滤器:应用:应用于如上述样本量巨大的黑名单,即要在巨大样本量..原创 2020-08-13 16:49:47 · 155 阅读 · 0 评论 -
关于哈希表 哈希函数
哈希函数特征:(1)输入域无穷大,输出域有限,且输出确定(即可能有多个不同的输入得到相同的输出,哈希碰撞)(2)假设将输出域抽象成一个区域,那么用一个小圈在范围内任意挪动,圈内点的数目都是差不多的,即输出点均匀离散的分布。(当然是在输入量相对大的情况下)题目现有40亿个无符号整数(4字节)的文件,只给1G内存,要求得到出现频率前十的整数。分析:(1)如果我们用哈希表来记录,那么无符号整数是0 ~ 42亿多,一条记录<整数,词频>需要8个字节,现有40亿个整数,故共..原创 2020-08-13 16:47:33 · 393 阅读 · 0 评论 -
数组左右部分最大值之差的绝对值尽量大
业务型题目:一个数组,要求把其切割成左右两个子数组,并要求左右两个子数组的最大值之差的绝对值要尽可能大。注意这里只是要求尽可能大。分析:分两种情况讨论,我们先找出数组中的最大值。假设最大值在右数组,由于左数组是肯定包含list[0]的;同理假设最大值在左数组,那么右数组肯定是包含list[k]。我们只需要比较这两种情况|max - list[0]|和|max - list[k]|两个的值谁大,就可以得出怎么切。即max在左数组还是右数组。...原创 2020-08-13 16:44:02 · 551 阅读 · 0 评论 -
最大子数组问题(延伸最大子矩阵问题)
题目如标题,一个数组中求子数组和的最大值。分析:(1)数组全为非负数,则解为数组所有值的和。(2)数组全为负数,则解为数组中最大的成员的值。(3)数组含有负数和非负数,最普遍的情况。解法:1.技巧型,通过假设。假如我们要找的子数组即是和最大的,也是长度最长的。那么这个数组应该满足以下性质:(1)i至k(k<j)的任何一个数组,其和都应该不小于0。因为若小于零那就应该从k+1开始到j才能满足最大子数组的要求。(2)以i-1为尾部的任一个数组,其和都应该小于0,同理。所以我们运用一个原创 2020-08-13 16:42:59 · 157 阅读 · 0 评论 -
暴力递归到动态规划--纸牌博弈问题
题目数量为N的纸牌,排成一排,每次只能取最左或最右的纸牌。现有赌怪两个,一个先手拿一个后手拿,拿到牌累加后较大者获胜,问获胜者拿取的牌加起来有多大。解法:1)写出递归当纸牌长度为N时,假设赌怪1是先手,那么赌怪2就是后手;但纸牌长度为N-1时,赌怪1就变成了后手,而赌怪2是先手。故需要两个函数来进行递归。先手函数:当left==right,只剩一张牌了,那肯定是先手的拿这张牌,所以返回这张牌。若不止一张牌,那么先手就要在这两种情况中选取较大值:拿掉左边的牌然后在剩下的纸牌中充当后手;..原创 2020-08-13 16:40:39 · 615 阅读 · 0 评论 -
暴力递归到动态规划--机器人移动
题目有N格(标号1~N),start为机器人初始位置,end为机器人目的地,k是机器人一定要走的步数。求从start开始走完k步到end的方案数。解法:1)暴力递归,代码如下,解释省略,这是最简答的思路。暴力递归问题在于会有许多重复的操作,如下图,多次暴力展开相同的情况。这也是暴力递归改动态规划唯一的理由,我们需要对走过的路进行存储,遇到时就可以直接用。2)优化1:记忆化搜索利用一个缓存ache,遇到一种情况先看缓存中有无次记录,有则直接拿取,无则计算并存储进表。虽然没有对..原创 2020-08-13 16:36:44 · 199 阅读 · 0 评论