
算法
文章平均质量分 80
ww32cc
这个作者很懒,什么都没留下…
展开
-
STL源码——排列生成算法(next-permutation、pre-permutation)
排列生成算法有三种:序数法、字典序法、换位法。本文只讨论前两种较常用的方法。一.序数法所谓序数,指的是某个排列在这n的数的所有排列中按字典序排序的序数。已知一个排列,可以用康托展开求其序数。假设排列为,这个排列对应的序数为。其中表示位于第i位右边比小的元素的个数,排列组合意义上理解:设当前排列,考察第位,第位比小的排列的一定比小,第位有中情况,后面的位的情况为,所以在位比排列小的排列有原创 2015-10-11 16:46:23 · 983 阅读 · 0 评论 -
求乘法逆元
若, 则称关于模的乘法逆元为,也可表示为,当且仅当时存在逆元。方法一:扩展欧几里得定理关于两个数的最大公约数,定存在两个数满足:,可能为负数。则当时,,则为模的逆元,为下面来推导存在什么样的关系,根据欧几里得定理上面的递推关系什么时候停止呢?在欧几里得算法求最大公约数时,算法最后停止于,而此时的系数一定满足:,为方便计算,可令。则根据递推关系,可以从最终状态推回到原始的。原创 2016-05-15 15:40:11 · 636 阅读 · 0 评论 -
Google APAC Test 2016 Not So Random 矩阵快递幂(logN复杂度)
题目描述:ProblemThere is a certain "random number generator" (RNG) which takes one nonnegative integer as input and generates another nonnegative integer as output. But you know that the RNG is re原创 2016-05-10 15:23:48 · 2019 阅读 · 3 评论 -
最近公共祖先(LCA)——离线Tarjan算法+并查集优化
LCA问题(lowest common ancestors):在一个有根树T中,两个节点和的原创 2016-04-12 22:23:44 · 2840 阅读 · 0 评论 -
manacher算法 O(n)求最长回文子串
朴素的做法是求出以每个字符为中心的回文串长度,复杂度为,还需要考虑奇数长度和偶数长度。而manacher算法可以在O(n)时间内求解,奇数长度和偶数长度可以统一处理。根据回文串的对称性,避免了大量不必要的比较。处理技巧:①相邻的字符之间插入一个分隔符,串的首尾也要加,以“#”为例,则长度为n的字符串经过处理之后变成2n+1奇数长度的字符串。为防止向两边扩展时越界,可以在首尾处加两个不匹原创 2015-09-29 20:30:24 · 518 阅读 · 0 评论 -
数组中只出现一次的三个数(简单解法)
一个int数组中除了三个数之外,其他数字都出现了两次,找出这三个只出现一次的数。思路:只有一个数只出现的情况下,对所有数进行异或,异或的结果即为所求;只有两个数只出现一次的情况下,一个数的我们会做了,两个数的话,如何将这些元素拆分成两组,使得这两个数分布在这两组中,然后就可以一一求解。还是从所有数异或的结果入手。由于这两个数不相等,所以异或的结果一定不为0,等价于:这两个数一定存在某一个bit原创 2016-03-19 10:50:06 · 1882 阅读 · 0 评论 -
Moore's majority vote algorithm
求n个数中出现次数超过原创 2016-02-08 11:19:23 · 406 阅读 · 0 评论 -
Morris traversal
对于二叉树遍历,现有的很多算法大多基于栈,递归或者迭代。下面是中序遍历的迭代版本:/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(原创 2016-01-03 21:00:12 · 548 阅读 · 0 评论 -
STL源码—— rotate算法理解
rotate算法实现了区间内元素的循环移位,将[first, middle)内的元素和[middle, last)内的元素互换,middle所指的元素会成为容器的第一个元素。如下图所示:由于不同迭代器造成算法的效率有所不同,因此设计为双层架构。templateinline void rotate(ForwardIterator first, ForwardIterator m原创 2015-10-09 16:29:57 · 1078 阅读 · 1 评论 -
有向图强连通分量Tarjan算法+ Codeforces Round #267 (Div. 2) D.Fedor and Essay
在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向图的极大强连通子图,称为强连通分量(strongly connected components)。 Tarjan算法基于有向图的DFS算法,每原创 2015-07-16 13:06:53 · 743 阅读 · 0 评论 -
STL源码——list sort:归并排序的非递归实现
由于STL中提供的sort算法是用在RandomAccessIterator上的,而list迭代器不具备随机访问的特性,所以对list进行排序不能使用algorithm中的sort算法,而应该使用list的成员函数sort。对list进行排序,最直接的想法就是用MergeSort,但是每次找中点就需要O(n),可能考虑到这点,成员函数sort并没有采用这种方式实现,而是用了非递归版的MergeSo原创 2015-12-13 13:45:59 · 834 阅读 · 1 评论 -
Nim博弈及其扩展
1.定义有若干堆石子,每堆石子的数量都是有限的,合法的移动是“选择一堆石子并拿走若干颗(不能不拿)”,如果轮到某个人时所有的石子堆都已经被拿空了,则判负。2.局面给出如下定义:P-Position:Previous-player 刚刚走过的选手得胜的局势;N-Position: Next-player将要走的选手得胜的局势;终结状态:没有合法的操作集。由Nim的定义,终结状原创 2015-09-21 17:10:04 · 1247 阅读 · 0 评论 -
双向BFS及优化
单向BFS只从起点一端开始搜索,双向BFS则是从起点和终点两边扩展节点,当节点发生重合时即找到最优解。假设起点到终点深度为d,每个节点平均有n个分支,那么单向BFS需要扩展的节点个数为。而从起点终点同时扩展,则只需。实现方法为:维护两个队列,分别保存从起点和终点扩展到的下一层,这样保证了两个队列中的节点处于相同的深度(即:距离起点或者终点深度相同)。则当拓展到时一定发生重合,得到最优解。代原创 2016-02-27 16:33:04 · 7510 阅读 · 0 评论