
数据结构与算法
文章平均质量分 59
程序员·小李
不知道要干什么的时候,停一停,想一想;知道想要什么的时候,努努力,拼一拼。
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
布隆过滤器
布隆过滤器的目标尽可能小的内存占用,完成哈希表的功能,判断给定Key是否存在,true/false的问题。由于存在假阳性的判断结果,所以一般作为预处理(预判断)使用。布隆过滤器的缺点布隆过滤器有失败率,是指实际不存在数据判定为已经存在(假阳性)。布隆过滤器的使用策略来了一个key后,经过多个哈希函数的判断,如果每个哈希都认定这个key存在的话,那么布隆过滤器视为这个key已经存在,否则,视为不存在。但也有可能与某个key发生碰撞,本来不存在的key,布隆过滤器视为存在,产生假阳性判断。原创 2023-02-03 07:58:10 · 571 阅读 · 0 评论 -
【数据结构与算法】红包算法
红包算法就是如何分配红包的问题。1. 单个红包的下限MIN_MONEY = 1(分)2. 单个红包的上限MAX_MONEY = 20000(分)3. 剩余金额的check结果枚举4. 为了防止某个红包数额过大,我们设置一个上限,即最大红包金额不得超过均值的TIMES = 2.1倍1. 通过设定最大值和最小值,约束红包的金额范围。2. 通过设定比例系数Times,来防止最大红包的金额过大的问题。3. 每次在最小值与最大值之间随机产生一个红包金额。4. 在产生新的红包后,验证剩余金额是否够分配。...原创 2022-07-07 07:32:48 · 657 阅读 · 5 评论 -
【排序算法】冒泡排序算法
问题描述给定一个无需数组,完成数组的排序,从小到大。算法描述冒泡算法:1. 依次比对前一个元素和后一个元素的大小,如果array[i] > array[i + 1]则进行交换,那么经过这次比对,会把最大的那个元素移动到数组的最后一个位置。2. 依次比对前一个元素和后一个元素的大小,如果array[i] > array[i + 1]则进行交换,直至倒数第二个元素。那么经过这次比对,会把第二大的那个元素移动到数组的倒数第二个位置。3. 以此类推。示例原创 2022-03-08 08:14:51 · 222 阅读 · 0 评论 -
【排序算法】选择排序算法
问题描述给出一个无序数组,按从小到大的顺序完成排序。算法描述1.把整个数组拆分成两部分:已排序 和 待排序。2.每次在待排序部分选择最小的元素,把它放在已排序部分。算法示例待排数组:arr[] = 64 25 12 22 11第一次,选中11,11 25 12 22 64第二次,选中12,11 12 25 22 64第三次,选中22,11 12 22 25 64第四次,选中25,11 12 22 25 64代原创 2022-03-07 22:19:16 · 290 阅读 · 0 评论 -
【查找算法】三分查找算法
问题描述有序数组的元素查找问题代码实现对比二分和三分查找:static int binarySearch(int arr[], int l, int r, int x){ if (r >= l) { int mid = l + (r - l)/2; // 先计算中间索引,判断是否恰好是中间值 if (arr[mid] == x) return mid; // 左侧查找 if (arr[mid] > x) return bina.原创 2022-03-07 09:01:44 · 2455 阅读 · 0 评论 -
【查找算法】指数搜索算法
问题描述仍然是查找问题,对于有序数组,如何迅速的找到指定的元素呢?Input: arr[] = {10, 20, 40, 45, 55} x = 45Output: 3Input: arr[] = {10, 15, 25, 45, 55} x = 15Output: 1算法描述依次比对第1,2,4,8,16,32,64,128。。。先找到合适的i,使得有 array[i / 2] < x < array[i]然后,从原创 2022-03-07 08:29:23 · 437 阅读 · 0 评论 -
【查找算法】插值搜索算法
问题描述给定n个元素的均匀分布的数组中,找到给定的元素的位置。啥叫均匀分布?最理想的状态就是,1,3,5,7,9。。。可以根据均匀分布的特点,计算目标值的预估位置执行步骤根据均匀分布的特点,每次找到差不多逼近目标值的那个值,然后进行二分逼近。代码实现class GFG { public static int interpolationSearch(int arr[], int lo, int hi, int x) { i..原创 2022-02-28 08:53:20 · 176 阅读 · 0 评论 -
【查找算法】跳跃式搜索算法
问题描述给定n个元素的数组,找到给定的元素的位置。适用场景当数组有序时,可以采用跳跃式搜索算法,可以减少一定数量的查找比对操作,整体复杂度为O(√n) (不如二分查找)他的效率介于线性搜索和二分查找之间。当使用二分查找效率不高的时候,可以尝试使用跳跃式搜索。执行步骤设置一个block大小m,从index=0开始比对,如果较小则index = index + m,以此类推,直到查到元素。如果我们发现前一个比对值比目标值小,后一个比对值比目标值大,那么目标值肯定在这原创 2022-02-28 08:31:21 · 648 阅读 · 0 评论 -
【查找算法】二分搜索算法
问题描述给定n个元素的数组,找到给定的元素的位置。适用场景当数组有序时,可以采用二分搜索算法,二分搜索可以折半进行,每次减少一半的查找比对操作,整体复杂度为O(Log n)执行步骤如果元素值小于当前的中间元素,元素去除较大的一半,否则如果元素值大于当前的中间元素,元素去除较小的一半,重复执行知道没有元素了或者找到相等的元素。递归代码实现int binarySearch(int arr[], int l, int r, int x){ if (r.原创 2022-02-28 00:03:21 · 222 阅读 · 0 评论 -
【查找算法】线性搜索算法
问题描述给定n个元素的数组,找到给定的元素的位置。示例Input : arr[] = {10, 20, 80, 30, 60, 50, 110, 100, 130, 170} x = 110;Output : 6x的位置是6Input : arr[] = {10, 20, 80, 30, 60, 50, 110, 100, 130, 170} x原创 2022-02-27 23:31:44 · 442 阅读 · 0 评论 -
希尔排序
算法原理将原来的插入排序进行改进,从大粒度进行插入排序到小粒度插入排序。算法步骤1.按照一定的gap进行插入排序2.缩小gap,再进行插入排序3.直到gap ==14.算法结束代码实现public class ShellSort implements IArraySort { @Override public int[...原创 2019-07-19 12:15:40 · 188 阅读 · 0 评论 -
【啊哈!算法】之深度优先与宽度优先
我们看下面的图我们现在要把所有的点都遍历一遍。使用深度优先搜索:1 > 2 > 4 > 3 > 5深度优先从1号节点出发,到达2号节点后,继续往深处走,找到4,再继续,找不到了,回到2,也没有其他节点可以访问了,回到1,再到3号节点,直到5号节点。我们使用邻接矩阵来表示他们的链接关系:因为是无向图,所以邻接矩阵是对称的。1...原创 2019-07-17 11:20:43 · 734 阅读 · 0 评论 -
【啊哈!算法】之图的深度优先搜索
对于给定的图,我们找到1号到5号的最短路径。使用邻接矩阵来描述:0表示自己,无穷大表示不可达,大于0的表示可达,距离是元素值。按照深度优先的思路从1号节点出发(1),我们发现可以到达2号和5号。先到达2号(1 -> 2),2号可以到达哪里?3号和5号。到达3号(1 -> 2 -> 3), 3号可以到哪里?4号。到达4号(1 ->...原创 2019-07-17 14:30:06 · 272 阅读 · 0 评论 -
【啊哈!算法】之图的广度优先搜索
我们仍然是从1到5,现在找到经过节点数最少的一条路线。其实把节点间的距离看做1的话,就是距离最短。我们使用广度优先的思路解决:首先,1号节点入队,找到与1号节点一步直达的节点,2号,3号2号3号入队,1号出队,找到2号节点一步直达的节点,1号,3号,4号,由于1号,3号都遍历过,只需要将4号入队。2号出队,找到3号节点一步直达的节点,1号,2号,4号,...原创 2019-07-17 14:48:20 · 557 阅读 · 0 评论 -
【啊哈!算法】最短路径之Floyd-Warshall
我们要求任意两个点之间的最短距离。我们仍然使用邻接矩阵表示他们之间的可达性及距离:我们前面直到深度优先搜索与广度优先搜索均可以解决最短路径问题。还有其他的方法吗?关于缩短路程的思考初始路程已经给定,如何减少两点之间的路程呢?我们试图设置一个固定点进行中转,也就是,我们假设,要么不中转。要么只能通过1号节点中转一次。那么,哪些路径经过1号节点中转是有意义的呢?...原创 2019-07-17 15:12:33 · 421 阅读 · 0 评论 -
【啊哈!算法】最短路径之Dijkstra
求从1号节点到任意一点之间最短路径。仍然用邻接矩阵来表示节点之间的可达性。我们拿出一个数组来存储1号节点到其他节点的初始路程:首先,我们找到1号节点到其余各点中最近的一个点,就是2号。那么,我们可以肯定,从1号到2号最短就是1了,因为他们之间直达,从1号节点到其他节点的最近的就是它,不可能通过其他节点中转变的更短。我们从2号出发,看看从2能到哪里。从2号能到达3...原创 2019-07-17 15:42:51 · 763 阅读 · 0 评论 -
【啊哈!算法】最短路径之Bellman-ford算法
迪杰斯塔拉不能解决边中存在负数的问题,我们引入本节的算法核心代码首先,我们遍历N-1次,N代表节点的个数。接着,在内部,对每一条边进行松弛:判断条件,对于u[i]节点到v[i]节点的距离w[i]可以使得从起点到v[i]节点的距离缩短的话,那么就说明可以松弛。实例我们计算从1号节点出发到其他任意一个节点的最短距离。初始化:第一轮松弛...原创 2019-07-17 16:02:42 · 778 阅读 · 6 评论 -
【啊哈!算法】最短路径之Bellman-ford优化算法
我们只对最短路径发生变化的相邻边进行松弛,这样可以优化Bellman算法每次选取队首顶点u,对于u所有的出边进行松弛,例如u->v如果有u->v使得路径变短,将v入队。对u出边进行松弛,松弛完毕后将u出队。直到队列为空。实例建立diss数组存储最短距离:将1号节点入队:从1号节点出发,可以到2号,可以对2号进行松弛。...原创 2019-07-17 16:20:39 · 632 阅读 · 0 评论 -
【啊哈!算法】二叉树
二叉树每个节点最多有两个子树。满二叉树所有的叶子结点都在最后一层,并且,最后一层也是满的。对于深度为h的树,他的节点数恰好是2^h - 1完全二叉树对于一棵树,是完全按照从上到下,从左到右排列的子树的话,这就是完全二叉树。啥意思,没有那种左子树缺失但右子树存在的现象。对于完全二叉树,如果父节点的编号是k,那么他的左子树是2...原创 2019-07-18 08:40:10 · 234 阅读 · 0 评论 -
【排序算法】桶排序算法
算法原理将元素根据大小划分到不同的桶中,对桶内的元素进行排序,按照桶的先后顺序输出即可得到最终的排序序列。算法步骤1. 找到最大元素与最小元素2.根据桶的个数计算每个桶的范围3.根据数值大小分配到不同的桶4.对桶内元素进行排序5.按照桶范围依次输出桶内元素。代码实现public class BucketSort implement...原创 2019-07-19 11:00:20 · 1002 阅读 · 0 评论 -
基数排序
算法原理以整数的排序为例,将数先根据个位数进行排序,再根据十位数进行排序。算法步骤1. 将个位数相同的放在一个桶里,然后依次输出。2.再将十位数相同的放在一个桶里,然后依次输出。3.直至最高位。代码实现/** * 基数排序 * 考虑负数的情况还可以参考: https://code.i-harness.com/zh-CN...原创 2019-07-19 10:31:21 · 550 阅读 · 0 评论 -
【啊哈!算法】之链表
对于存储大量数据的结构,频繁的进行插入删除操作,需要用到高效的链表。问题引入:对于已经排好序的2 3 5 8 9 10 18 26 32,我们希望在5的后面插入6,使得插入以后还是有序的。如果是数组的话,这个操作就麻烦了,需要后面的元素依次向后移动一位。链表链表不再约束于顺序的存储结构。我们只需要知道元素的相对位置前后即可。元素的插入:...原创 2019-07-15 19:06:00 · 683 阅读 · 0 评论 -
【啊哈!算法】之栈
想要拿到2号球,就得依次取出3号球与1号球。我们可以使用一个数组和一个栈顶指针实现。问题引入判断某个字符串是否是回文。解决思路1. 读取字符串,获取字符串长度。char a[101];int len;gets(a);len=strlen(a);2. 获取字符串中点mid=len/2-1;3.将中点前的元素入栈for(...原创 2019-07-15 17:50:37 · 342 阅读 · 4 评论 -
【啊哈!算法】之队列
问题引入给出一串数字,6 3 1 7 5 8 9 2 4,进行以下操作,删除第一个元素,将第二个元素排到最后,删除第三个元素,将第四个元素排到最后。获取删除的元素,直到最后剩余一个元素,也删掉。我们用数组实现一下:创建一个数组,用head指向第一个元素的位置,用tail指向最后一个元素的下一个位置。我们称head为队首指针,tail为队尾指针。队首队尾指向同一个位...原创 2019-07-15 17:18:46 · 247 阅读 · 0 评论 -
【啊哈!算法】之快速排序
冒泡排序对于时间复杂度来说是很大的,“桶排序”对于空间复杂度来说是很大的。问题引入我们现在要对6 1 2 7 9 3 4 5 10 8进行排序。首先,我们找到一个参考数,比如第一个位置的6吧!我们接下来就是把大于参考数的元素放到参考数的左侧,小于参考数的元素放到参考数的右侧。最终,参考数将会位于序列的中间某个位置。我们从序列的两端开始看,从右向左找小于6的数,从左向...原创 2019-07-15 16:40:37 · 433 阅读 · 0 评论 -
排序算法总概
两类排序算法1. 内部排序。所有的数据加载到内存中,一次性完成排序任务。2.外部排序。由于需要排序的数据量很大, 需要访问外部存储。常见的内部排序算法及其复杂度...原创 2019-07-11 11:06:39 · 200 阅读 · 0 评论 -
【数据结构】数据结构之堆
堆是什么?堆是一种特殊的完全二叉树。我们发现,堆不同于普通的完全二叉树,他有一定的规律。当任意一个节点既小于他的左子树又小于他的右子树,这样的树如果是完全二叉树的话,称为最小堆。当任意一个节点既大于他的左子树又大于他的右子树,这样的树如果是完全二叉树的话,称为最大堆。那么堆的存在有什么意义呢?我们试图对99,5,36,7,22,17,46,12,2,1...原创 2019-07-18 09:42:51 · 777 阅读 · 0 评论 -
【排序算法】计数排序算法
算法原理使用空间换取时间。对每个元素进行遍历,同时对相应的计数器的位置进行计数,最后按照计数器的顺序进行输出。算法步骤1. 生成一个最小数到最大数范围的存储空间(使得读写复杂度为O(1))2.对序列进行遍历,统计各个数的数量。3.遍历计数器,依次输出。代码实现public class CountingSort impleme...原创 2019-07-19 10:18:52 · 193 阅读 · 0 评论 -
堆排序
算法原理利用堆的性质进行排序,堆是一种近似于完全二叉树的数据结构,分为大顶堆和小顶堆。大顶堆:父节点元素值均大于或等于左子树、右子树的值。小顶堆:父节点元素值均小于或等于左子树、右子树的值。常使用大顶堆升序排列,小顶堆降序排列。时间复杂度O(NLogN)算法步骤1. 创建一个堆2. 把堆首(最大值)与堆尾的元素交换,向下调整。3...原创 2019-07-19 10:10:46 · 200 阅读 · 0 评论 -
【排序算法】归并排序算法
算法原理将待排序的元素划分到两个数组,分别对两个数组进行排序后,将两个数组进行合并。算法步骤1. 将待排序的元素划分到两个数组2. 分别对两个数组的元素进行排序。3. 使用两个指针分别指向两个排好序的数组的首地址,进行合并。4.得到合并后的数组即有序的数组。代码实现public class MergeSort implements...原创 2019-07-19 09:52:53 · 404 阅读 · 0 评论 -
快速排序
算法原理选择一个基准,将元素大于基准的往后放,小于基准的往前放。算法步骤:1.在数列中选择一个元素作为基准。2.重新排列数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面。3.重复上述步骤。算法性能:在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并...原创 2019-07-18 17:24:40 · 156 阅读 · 0 评论 -
【啊哈!算法】之广度优先搜索
问题引入我们需要在二维数组中搜索某个位置的元素的位置。就像从迷宫中找人一样。我们可以采用深度优先的思路进行搜索:首先在(1,1)点处找到一步到达的所有位置,(2,1)或者(1,2),针对(2,1)找到一步可达的位置,继续深层次递归。直到道路不通,再回到(2,1),切换到(1,2)再深层次递归。广度优先在(1,1)处,找到一步可达的点,(2,1)(1...原创 2019-07-16 10:40:46 · 860 阅读 · 0 评论 -
【啊哈!算法】之深度优先搜索
问题引入给定一个n,如何计算出1-n组成的数的全排列呢?例如,n = 3,数字是123,那么可能的组合是:123132213231312321实际上,问题可以描述为,有三张卡片,三个盒子,每个盒子必须有一张,每张卡片必须放在盒子里,这样的放置方法共有几种。问题尝试解决先将1号牌放到一号盒子:再将2号牌放到二号盒子再把3号牌放...原创 2019-07-16 09:55:17 · 709 阅读 · 0 评论 -
【啊哈!算法】之枚举
问题引入对于这样的奥数题大家一定不会陌生,实现起来也是没有什么难度的:for(i = 1;i<=9;i++){ if((i*10+3)*6528 == (30+i)*8256) { printf("%d",i); }}这就是采用枚举的方法,把所有的可能性都进行了尝试。对于形如这样的火柴棍,如何在全部使用给定的火...原创 2019-07-16 09:17:30 · 282 阅读 · 0 评论 -
【排序算法】插入排序算法
从第二个元素开始,以左侧元素已经有序为前提,向前依次对比,就像站队一样找到自己的位置。前面的同学(元素)比自己高(大),就让他往后挪一个位置,直到发现前面的那个比自己矮(小),或者前面已经没有其他人(元素)了。82比67大,往后稍稍,61比67小,不需要移动了,因此排序后的 元素是61,67,82。前面任何元素都比4大,因此每个都得往后移动一下。61比82元素小,82不需要处理了,因此当前已经是有序的了。此时,我们认定61是有序的,从82开始进行排序即可。时间复杂度:O(n^2)空间复杂度:O(1)原创 2019-07-11 16:22:59 · 193 阅读 · 0 评论 -
单链表倒置
问题描述:所谓单链表倒置就是头变成尾,尾变成头,指针逆向。方法一:递归法public ListNode Reverse(ListNode node){ if (node.next == null) return node; var prevNode = Reverse(node.next); var temp = no...原创 2019-07-12 18:11:27 · 551 阅读 · 0 评论