
算法及数据结构
对数据结构及算法题进行收集解决,题目来自LeeCode、牛客网、各OJ系统等,网站尽量对每个题做到尽可能多的解决方案,考虑完成java、C++等题解。注:供学习用,侵权删!
BoCong-Deng
翻过这座山,别人就能听到你的故事!
展开
-
只出现一次的数算法题汇总
这篇文章用来总结一个系列的算法题,也就是找到元素数组中重复出现的元素或者只出现一次的元素。其实在讲解之前,如果之前有接触过这类的类的同学,应该知道解决这类题的方式不外乎用位运算来搞定。使用位运算来解决这一系列问题很有趣,这也是为什么我想着专门写一篇博文来记录的原因,废话不多说,咱们进入正文。原创 2020-05-20 14:11:18 · 1658 阅读 · 0 评论 -
一些通过数学分析解决的算法题汇总
写在前面如果觉得写得好,或者有所帮助,记得点个关注和点个赞,不胜感激!我发现最近经常会遇到一些需要通过数学分析去解决的问题,做的时候想着各种方法,然后看到题解,发现可以用数学分析的方式,找到非常快的解决办法,整个人就emmmmm了,所以这里开这篇博文,用来记录自己碰到的可以用数学分析的方式解决的算法问题,不断更新。“树根”相关问题“树根”在维基百科的定义如下:在数学中,数根(又称位数根或数字根Digital root)是自然数的一种性质,换句话说,每个自然数都有一个数根。数根是将一正整数的各个位数原创 2020-05-19 17:20:45 · 942 阅读 · 0 评论 -
搜索二维矩阵(左右上下升序,寻找目标值)
数组从左到右和从上到下都是升序的,如果从右上角出发开始遍历呢?会发现每次都是向左数字会变小,向下数字会变大,有点和二分查找树相似。二分查找树的话,是向左数字变小,向右数字变大。所以我们可以把 target 和当前值比较。原创 2020-05-10 18:47:28 · 957 阅读 · 0 评论 -
滑动窗口最大值问题
其实这里的话,我们需要先理解双向队列,这个是一个很有用的数据结构,他可以让我们在 $O(1)$ 的时间复杂度内,访问头部和尾部的节点。所以,我们可以使用双向队列来帮助我们,实现 $O(N)$ 时间复杂度内,得到结果。处理前 k 个元素,初始化双向队列。原创 2020-05-09 19:37:17 · 547 阅读 · 0 评论 -
二叉树的公共最近祖先问题
我们上面的第一直觉就是我们通过记录两个节点的路径,再来找公共祖先,但是其实我们在遍历的过程中,就可以通过记录当前祖先的方式,找到公共祖先。不过和上面的思路的遍历方式区别的地方在于,上面的思路是通过层次遍历,而这种方式是通过深度遍历。原创 2020-05-08 11:32:34 · 1829 阅读 · 0 评论 -
计算阶乘之后的零个数
我觉得吧,以后像这种纯粹就是进行数学分析的问题,我就要把它记录下来,这种问题给你时间让你去分析,可能就能分析出来,但是限定你时间让你解决,很容易卡住,所以遇到了就学习思路,然后以后如果碰到类似的问题,那么解决起来就非常迅速利落了。原创 2020-05-04 19:04:44 · 1604 阅读 · 1 评论 -
计算数字 1 的个数(小于等于 n 的非负整数中数字 1 出现的个数)
这个问题乍一看,我最开始以为是计算二进制位的1的个数(最近对二进制比较敏感,想啥问题都是先想着能不能二进制解决)。然后仔细看了问题之后才发现,其实就是计算十进制中1的个数。其实理解问题之后,感觉也不是很难,一个暴力计算就搞定,不过,光用暴力解决问题并不是我的风格,所以还要想着其他更有效的方式。这里记录这个问题,不是因为他有多难,而是这个问题其实是一个纯粹的数学问题,我们需要进行数学分析就可以很简单的实现出来并解决,而不是使用语言上的奇淫巧技。原创 2020-05-04 18:36:56 · 2856 阅读 · 2 评论 -
摩尔投票算法(Boyer-Moore Voting Algorithm)
给定一个数组A,其中含有 n 个元素,在数组A中出现超过 n/2 次的元素,也就是出现次数超过 n/2 的众数。现在的问题要求找到数组中是否存在这样的元素,其出现次数超过 n/2。现在本文就来讨论在线性复杂度下,计算成本最优的算法。原创 2020-05-03 18:45:49 · 1131 阅读 · 1 评论 -
不用找了,学习BM算法,这篇就够了(思路+详注代码)
为什么说循序渐进,是因为BM算法,在大多数情况下,表现的比KMP算法优秀,所以大部分时候,都当做KMP进阶的算法来学习。BM算法从模式串的尾部开始匹配,且拥有在最坏情况下 $O(N) $的时间复杂度。有数据表明,在实践中,比 KMP 算法的实际效能高,可以快大概 3-5 倍,很值得学习。在学习BM算法的时候,找了很多资料,也遇到了很多优秀的文章,不过目前还没有碰到即讲清楚了原理,又实现了代码的文章,java版的更是不容易找原创 2020-04-17 18:38:34 · 26973 阅读 · 14 评论 -
总结一下动态规划的思路
我相信只要是接触算法的同学,就一定会接触DP,也就是动态规划,虽然经常遇见动态规划相关的算法题,但是许多人还是有些畏惧,不过我相信只要你愿意静下来学习总结,看看这篇文章或者其他优秀的讲解文章,不管你之前是否害怕动态规划系列的问题,相信足以帮助你消除对动态规划算法的恐惧,因为动态规划其实就是套路中,寻求变数。只要有掌握了套路,就能灵活应对。原创 2020-04-15 16:32:21 · 5036 阅读 · 0 评论 -
把KMP匹配算法讲清楚
KMP算法是真的折磨我够呛的,记不清是大一还是大二的时候就接触了这个算法,当时研究的一知半解,然后就用起来了,顶多只能说是敲多了几遍,大致的结构流程能够写出来,然后就一直用了很久到现在。虽然使用的过程中一直有磕磕碰碰,但是够用所以就没有进行深究,知道前段时间,包括今天,莫名其妙遇到了许多使用KMP思想,并进行变种的算法思路,以及算法题的解法,我才终于下定决定要把KMP算法搞明白,写下这篇博文,尝试吃透讲明白KMP。原创 2020-04-14 17:25:53 · 2379 阅读 · 6 评论 -
带你理解 Trie 树(前缀树)
在计算机科学中,Trie,又称前缀树或字典树,是一种有序树,用于保存关联数组,其中的键通常是字符串。与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定。一个节点的所有子孙都有相同的前缀,也就是这个节点对应的字符串,而根节点对应空字符串。一般情况下,不是所有的节点都有对应的值,只有叶子节点和部分内部节点所对应的键才有相关的值。Trie中的键通常是字符串,但也可以是其它的结构。Trie的算法可以很容易地修改为处理其它结构的有序序列,比如一串数字或者形状的排列。比如,Bitwise Trie中的原创 2020-04-10 16:50:39 · 654 阅读 · 0 评论 -
带你了解有向无环图和拓扑排序
在图论中,如果一个有向图无法从某个顶点出发经过若干条边回到该点,则这个图是一个有向无环图(DAG图)。而提到DAG,就差不多会联想到拓扑排序,拓扑排序是指由某个集合上的一个偏序得到该集合上的一个全序的操作。拓扑排序常用来确定一个依赖关系集中,事物发生的顺序。拓扑排序是对有向无环图的顶点的一种排序,它使得如果存在一条从顶点A到顶点B的路径,那么在排序中B出现在A的后面。DAG在区块链中得到很广泛的应用哦。原创 2020-04-09 19:19:42 · 4908 阅读 · 1 评论 -
这篇能让你搞懂股票买卖系列问题
写在前面如果觉得写的还不错,有所收获,记得点个关注和点个赞哟,不胜感激。股票买卖的这个系列问题早在之前就在LeetCode就刷了一遍了,不过当时因为一些原因,没有总结成一篇博文。后面又陆陆续续遇到了类似的问题,总感觉股票系列问题的奇技淫巧太多了,平时用来学习和拓展完全是没有问题的,不过如果到了一些正式场合,一般不会想到那些巧妙的办法,怎么办呢?所以这一篇博文就打算稳扎稳打,通过较为详细的讲解,...原创 2020-04-03 12:02:23 · 559 阅读 · 0 评论 -
你想要的排序算法,都在这!
基数排序、计数排序、堆排序、希尔排序、快速排序、选择排序、插入排序、归并排序。最近写代码的时候用到堆排序解决一些问题,然后写的过程中发现有点手生,就想着记录一些,然后又琢磨着干脆直接整理一份排序的文章,附带对排序的分析以及实现代码,给自己练练手。原创 2020-03-31 11:09:33 · 424 阅读 · 0 评论 -
不再惧怕!二叉树结构相关算法总结
树结构对于程序员来说应该不陌生,特别是二叉树,基本只要接触算法这一类的都一定会碰到的,所以我打算通过一篇文章,对二叉树结构的相关算法进行总结汇总,思路和代码实现相结合,让你不在惧怕二叉树。(ps:后面我还想写一篇树结构的高级篇,就是多叉数,就是对我平时看算法论文碰到的一些新奇的算法,比如B树、B+树,还有我一种叫做Bed树的新奇算法等等)原创 2020-03-03 18:47:02 · 11339 阅读 · 0 评论 -
详细总结组合排列的十余种算法实现
目录•写在前面•问题引入•暴力枚举循环枚举递归枚举回溯枚举•深度优先搜索前序遍历中序遍历后序遍历•字典序•二进制位运算•带重复数字•总结•写在前面排列组合的问题,如果没有合适的算法去解决,时间复杂度会相当的大,毕竟阶乘的时间复杂度不仅让人头大,也让他计算机欲罢不能,而且我们遇到排列组合的相关问题的概率相当的大,所以非常有必要掌握...原创 2020-02-10 22:37:51 · 24094 阅读 · 3 评论 -
一文学会快速傅里叶变换(FFT)
目录•写在前面•讲一讲多项式多项式的系数表示法多项式的点值表示法多项式的乘法•了解一下复数复数中的单位根•离散傅里叶变换(DFT)•离散傅里叶逆变换•快速傅里叶变换实现Fortran源码C++代码•参考资料•写在前面快速傅里叶变换是一种可在 时间内完成的离散傅里叶变换算法。在算法竞赛中的运用主要是用来加速多项式的乘法。我们这里做一个简单...原创 2020-02-08 22:36:08 · 13902 阅读 · 0 评论 -
详解编辑距离算法-Levenshtein Distance
目录•写在前面•什么是编辑距离?•思路•思路可视化•代码实现•写在前面编辑距离算法被数据科学家广泛应用,是用作机器翻译和语音识别评价标准的基本算法。最简单的方法是检查所有可能的编辑序列,从中找出最短的一条。但这个序列总数可能达到指数级,但完全不需要这么多,因为我们只要找到距离最短的那条而不是所有可能的序列。这个概念是由俄罗斯科学家Vladimir Levenshtein...原创 2020-02-06 18:19:03 · 27888 阅读 · 7 评论 -
牛顿迭代法求开方-详细且通俗讲解
目录•写在前面•前戏-二分法实现•牛顿迭代法代码实现•写在前面求开方这件事儿,很多时候用一个sqrt方法就搞定了,很少有趣思考这底层的实现到底是用什么方法完成的。正好我遇到了需要实现sqrt方法,这里就仔细的讲解一下如何去实现sqrt,当然啦,这里会进行一些数学原理的推算,不想看这些数学原理的推算的,也可以直接跳过,看文字描述的原理思路,我分好目录了,哈哈哈。•前戏-二...原创 2020-02-05 18:51:09 · 17092 阅读 · 2 评论 -
详解交换两个数的五种思路
目录•写在前面•利用新变量•利用加减法•利用乘除法•利用异或•利用移位•写在前面交换两个数?听起来这不是很简单嘛,感觉没什么好讲的。不过这么想是因为很多时候都想简单了,没有把编程的巧妙使用到极致,那么接下来我们来看看,交换两个数这么简单的问题,怎么玩出不一样的花出来,哈哈哈。•利用新变量这种方法是非常非常基本的一种方式,直接利用一个新的变量作为中介,交换两个...原创 2020-02-03 17:14:25 · 12004 阅读 · 0 评论 -
神奇的Knuth洗牌算法
目录•写在前面•一个公平的随机算法?•Knuth算法•证明思路•写在前面谈到随机算法,我们可能脑子里会出现很多种解决方案(ps:想不到解决方案的,可能是random函数用多了,哈哈哈),不过我这里要讲的Knuth随机算法,在我第一次接触到之后,就不得不感叹一声,确实很神奇,它的神奇之处不在于这个算法有多高深,实现有多复杂,而是在于这个算法的思想极其简单,简单到核心代码就两行...原创 2020-01-17 18:18:45 · 1692 阅读 · 0 评论 -
正则表达式匹配(详细多解法)
目录•写在前面•题目•解法一•解法二•解法三•写在前面所谓真的勇士,敢于直面不用API的手撕,我最开始看到这道题的时候,觉得简直就是到秒杀题,不过我还是按捺住了内心用java正则表达式API的冲动,手撕匹配代码,算法使用的思想就是递归,我最开始是使用直接递归解决了这道题,后面看别人的解法的时候,发现在递归上进行了改进,使用了动态规划的思路,降低了子串创建的时间成本,觉得...原创 2019-12-11 18:50:01 · 1661 阅读 · 0 评论 -
最大数问题(自定义排序)
目录•写在前面•题目•解法•写在前面最大数问题,不是选中最大的那个数,而是组合成最大的那个数,不是说这个问题有多难,而是说提供了一种很棒的思路,就是自定义排序,我觉得很值得收录,因为使用这种思路可以解决很多问题。话不多说,直接上题。•题目给定一组非负整数,重新排列它们的顺序使之组成一个最大的整数。示例 1:输入: [10,2]输出: 210示例2:输...原创 2019-12-08 21:27:14 · 707 阅读 · 0 评论 -
最长回文子串(多种解法,附马拉车算法)
目录•写在前面•题目•解法一 暴力破解•解法二 暴力优化•解法三 最长公共子串(动态规划整体)•解法四 中心扩展法•解法五 马拉车算法•结束•写在前面这种类型的题目算是比较常见的,有很多种解决方案,但我想着重说一下马拉车算法,第一因为之前我没有接触了解这个算法,第二就是,这个算法的时间复杂度降到了O(n),我自己在写的时候是使用中心扩展法进行解决的...原创 2019-12-08 17:59:20 · 788 阅读 · 0 评论 -
寻找两个有序数组的中位数(附上三种解法)
目录•写在前面•题目•解法一•解法二•解法三•结束•写在前面这道题比较经典,我当时在做的时候,想出了两种解决方案,不过总感觉算法不够优美,所以找到了另一种我觉得非常精妙的解法,利用了K最小数的思想去解决这道题,很值得讲一下,不知道K最小数的,可以参考我另一篇文章,点击这里跳转就可以了。下面我废话不多说,直接开始讲解。•题目首先先把题目呈上来,具体题目如下:...原创 2019-12-06 18:23:32 · 17144 阅读 · 6 评论 -
悬线法
悬线法思路:悬线法,悬线的定义,就是一条竖线,这条竖线要满足上端点在整个矩形上边界或者是一个障碍点。然后以这条悬线进行左右移动,直到移至障碍点或者是矩阵边界,进而确定这条悬线所在的极大矩阵。也就是说,我们要针对矩阵中每个点进行求极大矩阵的操作,所以我们需要Left[]数组存每个点能到达的最右位置,Right[]数组存放每个点能到达的......原创 2017-08-23 11:12:15 · 10824 阅读 · 3 评论 -
广度优先搜索
广度优先搜索的思路:了解过深度优先搜索的人应该知道,深度优先搜索的实现一般为栈、递归或者优先队列,而广度优先搜索的实现常常用普通的队列,而且其思想较易于理解。它的实际思想就是从起点出发,把起点周围方向上的点存入队列,在从队列头取出一个点,再将该店方向上的点存入队列,重复存取操作,直到遇见符合条件的点则退出函数,或者一直没有符合条件的点,则直......原创 2017-08-27 17:36:01 · 913 阅读 · 0 评论 -
快速幂取模(详细)
快速幂取模的用途:在ACM这类竞赛中,可能会遇到指数型的数据取模问题,这个时候如果直接用int或者long long储存,就有可能会超出计算机整数的存取范围,而导致数据出错。所以我们需要一种方法进行计算。而这种方法就是我们这次要讲到的快速幂取模(简称快速幂)。这种算法在时间和空间上都做了尽可能的优化,所以学会之后,会觉得非常好用。快速幂取模的思路:快速幂实现的最基本的理论就是我们...原创 2017-08-28 12:23:21 · 30483 阅读 · 20 评论 -
线段树
目录线段树的用途线段树的思路线段树的实现总结线段树的用途线段树,顾名思义,就是对线段序列按照树的方式进行操作。这样,线段序列就可以摒弃查询,增加等操作中的遍历而导致的低效率,从而得到树状结构的log(N)的时间复杂度的优化。线段树一般用于计算线段序列中,某区间元素数的总和,而且这个线段序列是经常进行改动操作的,这个时候,你就要不断的对序列中的每个元素进行更新,并不断的遍历。...原创 2017-08-30 11:59:32 · 683 阅读 · 0 评论 -
树状数组(详细)
我们这用含八个元素的数组来解释树状数组(图中的第九个元素直接忽略)。在研究算法的时候,我们需要先研究c数组(保存1~k区间的和)是按照一种什么样的规律进行计算的。C8 = C4 + C6 + C7 + a8,C4 = C2 + C3 + a4......。你把c数组里原创 2017-09-01 19:50:55 · 2475 阅读 · 0 评论 -
并查集
在用途中说过,并查集一般用在“不同类”的问题中,所以它存在一个“找关系”的特点。说白的,并查集其实就是将群集中的元素分为各个派别,在每个派别中存在上下级的关系,自然而然地,每个派别需要一个老大,而这个老大就被当成这个派别的首领(也就是......原创 2017-09-02 14:54:27 · 656 阅读 · 0 评论 -
迪杰斯特拉最短路径
逻辑主线:第一步:将与起始点直接连接的点的距离储存在dist数组中,找出到其中最短路径的点。如图中的点“2”,则10就是点“1”到点“2”的最短路径,因为从“1”经过其他点间接连接点“2”的点一定会比10 大......原创 2017-10-05 11:06:49 · 788 阅读 · 0 评论 -
深度优先搜索(附剪枝和优先队列的说明)
深度优先搜索的思路:搜索其实就是一种遍历,只不过这种遍历更形象成一种树形结构,从最开始的根节点出发,一直到树的尾端,在从“根”到“尾”的过程中,你就可以进行一些判断及操作。如果从“根”到其中一个“尾”都没有满足......原创 2017-08-26 14:22:19 · 5231 阅读 · 0 评论