算法
FlushHip
凝视深渊
展开
-
三分算法
Description: 三分算法其实是相对于二分的。与二分神似。它的作用主要来求一些凹或凸函数的极值的。当然,如果你高数可以的话求导也是可以解决的。 Code:double deal(){ double l=0,r=PI,mid,mmid; while(fabs(r-l)>EPS){ mid=(r+l)/2; mmid=(mid+r)/2;原创 2016-04-01 17:24:15 · 738 阅读 · 0 评论 -
剑指Offer66题之每日6题 - 第八天
原题链接:第一题:左旋转字符串;第二题:翻转单词顺序列;第三题:扑克牌顺子;第四题:孩子们的游戏(圆圈中最后剩下的数);第五题:求1+2+3+…+n;第六题:不用加减乘除做加法;第一题:左旋转字符串题目: 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后...原创 2018-02-05 16:38:56 · 1622 阅读 · 0 评论 -
剑指Offer66题之每日6题 - 第七天
原题链接:第一题:数字在排序数组中出现的次数;第二题:二叉树的深度;第三题:平衡二叉树;第四题:数组中只出现一次的数字;第五题:和为S的连续正数序列;第六题:和为S的两个数字;第一题:数字在排序数组中出现的次数题目: 统计一个数字在排序数组中出现的次数。解析: 这个题最简单的做法就是,两次查找,一次从前面往后找,找到第一个数字,一次从后面...原创 2018-02-05 16:36:49 · 2114 阅读 · 0 评论 -
剑指Offer66题之每日6题 - 第六天
原题链接:第一题:整数中1出现的次数;第二题:把数组排成最小的数;第三题:丑数;第四题:第一个只出现一次的字符位置;第五题:数组中的逆序对;第六题:两个链表的第一个公共结点;第一题:整数中1出现的次数题目: 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此...原创 2018-02-24 10:06:29 · 1809 阅读 · 0 评论 -
剑指Offer66题之每日6题 - 第十天
原题链接:第一题:链表中环的入口结点;第二题:删除链表中重复的结点;第三题:二叉树的下一个结点;第四题:对称的二叉树;第五题:按之字形顺序打印二叉树;第六题:把二叉树打印成多行;第一题:链表中环的入口结点题目: 一个链表中包含环,请找出该链表的环的入口结点。解析: 这其实就是一道小学的奥数题。 具体解答请看链表中环问题集合...原创 2018-02-27 18:09:53 · 1109 阅读 · 0 评论 -
链表中环问题详解
这个问题在面试中是老生常谈的问题了,而且,解决这类问题的主要方法就是追击法,因此,这篇博客中只讲解这种方法求解环的问题。这里给出三个链表中环的问题:判断链表中是否存在环;如果有环,求出环的入口;如果有环,求出环长。这里给出一副图片,所有的讨论都在这图片上进行。问题一:判断链表是否有环这个问题很好解决,设置两个指针ptr_1, ptr_2在A处,让ptr_1以1的...原创 2018-02-27 14:57:55 · 1321 阅读 · 1 评论 -
剑指Offer66题之每日6题 - 最后一天
原题链接:第一题:序列化二叉树;第二题:二叉搜索树的第k个结点;第三题:数据流中的中位数;第四题:滑动窗口的最大值;第五题:矩阵中的路径;第六题:机器人的运动范围;第一题:序列化二叉树题目: 请实现两个函数,分别用来序列化和反序列化二叉树解析: 这个题其实很不清楚,序列化的规则是什么?题中并没有给出,而且,题中要你序列化和反序列化二叉树,...原创 2018-02-26 17:55:33 · 1282 阅读 · 0 评论 -
剑指Offer66题之每日6题 - 第九天
原题链接:第一题:把字符串转换成整数;第二题:数组中重复的数字;第三题:构建乘积数组;第四题:正则表达式匹配;第五题:表示数值的字符串;第六题:字符流中第一个不重复的字符;第一题:把字符串转换成整数题目: 将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0解析: 模拟题,先处理空...原创 2018-02-26 17:09:59 · 1494 阅读 · 1 评论 -
剑指Offer66题之每日6题 - 总结、目录
剑指Offer每日6题系列终于在今天全部完成了,从2017年12月27日到2018年2月27日,历时两个月的写作,其中绝大部分的时间不是花在做题上,而是花在写作上,这个系列不适合大神,大牛,这个系列是我专门为那些初识算法,数据结构的同学和对基础算法,基本数据结构不熟练的同学而写的。里面所有的博文,我尽量避开生僻的一些概念,尽量用生活中的语言和例子来解释一些原理,因此在学术上可能不太严谨,但是,...原创 2018-02-27 19:12:47 · 5834 阅读 · 5 评论 -
序列逆序对问题详解
有关逆序对的概念,请参考百度百科逆序对。知道了逆序对的概念,那么在程序中可以很容易地用枚举法暴力求出逆序对,时间复杂度为O(n2)O(n2)O(n^2),对于n<104n<104n < 10^4的数据,这种方法是吃得消的,但是当数据变大时,这种方法就很容易超时,因此要进行优化。这里讲两种方法,一种是改变统计的算法,即归并排序求逆序;另一种是改变储存的数据结构,使其在统计的时候效...原创 2018-02-24 10:03:26 · 2527 阅读 · 0 评论 -
二分以及编程过程中求中点各种写法思想解析以及完美写法
在你真的理解二分的写法吗 - 二分写法详解这篇博客中,有几个朋友给二分求中点mid = (l + r) / 2提出了一些疑问和改进。自己最近也对这个问题有过一些思考,因此在这里系统详细地聊聊自己的看法,看看程序中求区间终点到底应该怎么写才是完美的。先公布程序中求区间中点的完美写法:mid = l + (r - l) / 2。在数学上,mid = l + (r - l) / 2和mid = ...原创 2018-09-02 22:42:13 · 4188 阅读 · 2 评论 -
ST算法处理RMQ和RGQ问题的4个例题
ST算法处理RMQ和RGQ举例POJ3264 - Balanced Lineup洛谷1890 - gcd区间ST算法简单应用POJ3368 - Frequent valuesHDU5726 - GCD原创 2018-07-30 00:10:38 · 845 阅读 · 0 评论 -
完全理解ST稀疏表在线处理RMQ问题及RGQ问题
ST是什么STSTST的全称是SparseTableSparseTableSparse\quad Table。谷歌上的解释如下: Sparse Table is a data structure that answers static Range Minimum Query (RMQ). It is recognized for its relatively fast query an...原创 2018-07-20 13:52:59 · 1401 阅读 · 0 评论 -
两道关于序列变换(把无规则的序列变成有规则的序列)的好题
最近对于序列变换这类题的解法有一种心得,想分享给大家。给大家三个题,其实是两个题,后两个题是一样的。把两个题放在一起,这样可以让你对这类题目有更深刻的理解。牛客练习赛16 - B题:漂亮的树题目链接:点这儿。#include &lt;bits/stdc++.h&gt;using namespace std;int main(){ for (int n; E...原创 2018-05-23 16:40:29 · 1397 阅读 · 2 评论 -
51NOD2000 - 四边形分割平面(使用矩阵求通项公式)
这道题挺有意思的,和HDU5047 - Sawtooth[找规律]的类型是一样的,关键问题在于你要知道如何分割使得区域个数最多以及求出递推公式或直接公式。题目链接:点这儿。我们先来看一张图,看看如何叠加正方形使得分隔的区域数最多。 这么叠加会生成最多的分隔区域,具体分析可以参考HDU5047 - Sawtooth[找规律]。因此可以得到递推式:Fn=Fn−1+8(n−1)Fn=F...原创 2018-06-03 06:51:12 · 616 阅读 · 0 评论 -
51NOD距离之和最小三个版本的解析
这三个版本根据难易程度依次排序:51NOD1096 - 距离之和最小51NOD1108 - 距离之和最小V251NOD1110 - 距离之和最小V3都是线段上一点到其余各点的距离和最小,或者是其变形。1096 - 距离之和最小这是个基础题,很明显,这个点应该选在中位数。依据是这个绝对值不等式|x−p|+|y−p|≥|x−y||x−p|+|y−p|≥|x−y||x-p| + ...原创 2018-05-15 18:56:36 · 630 阅读 · 0 评论 -
深入浅出矩阵快速幂及其简单应用
矩阵快速幂的基础是乘法快速幂,乘法快速幂可以看完全理解乘法快速幂及其两种写法的解析,只不过an=?an=?a^n=?换成了 An=?,A=⎡⎣⎢⎢⎢⎢a11a21⋮am1a12…⋮am2……⋮…a1na1n⋮amn⎤⎦⎥⎥⎥⎥An=?,A=[a11a12…a1na21……a1n⋮⋮⋮⋮am1am2…amn]\begin{equation*}A^n=? \qquad , A=\begin{bma...原创 2018-04-29 01:26:52 · 4360 阅读 · 3 评论 -
完全理解乘法快速幂及其两种写法的解析
an=?0≤n≤10105an=?0≤n≤10105a^n=? \qquad 0 \le n \le 10^{10^5} 没错,乘法快速幂就是解决上述问题的。乘法快速幂的思想可以看到,要求一个数的aaa的nnn次幂,而且这个nnn非常大,如果利用循环来处理,O(n)O(n)O(n)的时间复杂度对于计算机的处理速度来说是远远不够的;循环既然不能满足要求,那我们能不能加速一下这个循环...原创 2018-04-24 18:02:13 · 2140 阅读 · 3 评论 -
树上倍增法求最近公共祖先LCA
LCA,最近公共祖先,这个东西有很多作用,因此,如何高效求出LCA就成了一个热点的讨论话题。下面所有的讨论都以图中这棵树为例子。先来了解下什么是倍增吧,倍增其实就是二分的逆向,二分是逐渐缩小范围,而倍增是成倍扩大。这里的倍增借用二进制来表达更容易理解;原创 2018-02-26 13:33:06 · 913 阅读 · 1 评论 -
你真的理解二分的写法吗 - 二分写法详解
说实话,我之前也不完全理解二分查找的各种写法,导致在写各种二分的边界时我总是弄不清边界值,于是我只能通过暴力枚举这些边界值,去一个一个试,这样子效率真的很低下。于是,痛定思痛,一定要把二分的写法吃透,就有了这篇文章。二分写法的种类二分写法的种类很多,最常见的就是二分查找了的最普遍写法了。代码如下:bool bFind(int a[], int left, int right,原创 2018-02-05 16:35:24 · 9828 阅读 · 7 评论 -
HDU5783 - Divide the Sequence(2016 Multi-University Training Contest 5 - C)
Problem : Divide the Sequence Description : 给你一个序列,让你分割成连续的段。使得这些连续的子序列的每个前缀和都是非负数。问你最多能分成多少个段。Solution : 贪心。我们考虑这样一个问题,如果这个序列的每个数都是非负数,那么我们肯定把每个数都作为一个段那么答案就是这个序列的长度,但是,现在这个序列中出现了负数,我们要把这个段延伸才能原创 2016-10-12 11:10:25 · 475 阅读 · 0 评论 -
最小环
算法: 在一个图中求出一个路径长度最小的环。首先,我们可以想到迪杰斯特拉算法,计算出dis[src,i]dis[src,i]+map[i][src]map[i][src],然后维护一个最大值就好了。但是这样做的话,在计算dis[src,i]dis[src,i]时有可能会把map[i][src]map[i][src]包含进去,那么怎么办呢,我们可以枚举每一条边,先删掉,然后求dis[src,i]d原创 2016-08-08 09:52:27 · 791 阅读 · 0 评论 -
MCMF算法
最小费用最大流算法: 以费用作为权值,求出最小费用链,然后在这条链上求得一个最小流量,直到找不到费用链。求最小费用链也就相当于求src−>dessrc->des的最短路径。使用spfa+EKspfa+EK算法。得到MCMFMCMF算法代码:#define MIN(a,b) ((a)>(b)? (b):(a))using namespace std;const int INF=0x3f3f3f3原创 2016-08-04 15:34:27 · 2548 阅读 · 0 评论 -
DINIC算法
DINIC原理 DINIC算法和EK算法原理其实是一样的,都是寻找增广路,但是在实现的细节上不同,首先,用bfs对顶点进行层次编号,当汇点不在层次图中的时候算法结束;其次,用dfs寻找增广路,在dfs中,用一个顶点扩展时,其实计算了多条增广路,这也是这个算法比EK算法快的原因。Code#include <stdio.h>#include <string.h>#include <io原创 2016-07-28 10:36:15 · 1148 阅读 · 0 评论 -
EK算法
EK原理EK算法是求网络流最大流的算法。也称为寻找增广路算法,每次寻找一条增广路,求出这条路上最小的容量(木板原理),然后累加起来,直到最后找不到一条增广路为止。注意,在找到最小容量的时候,前向边要减去最小容量,而后向边要加上最小容量。这是为了形成能改正之前寻找增广路错误的残余网络,实际上这就是把之前的容量退回去,形成新的可行路径。Code#include <stdio.h>#include <原创 2016-07-28 09:39:30 · 1261 阅读 · 0 评论 -
Havel算法
判断一个序列是否可图化可以用到Havel算法。这个序列被看成是这个图中的点的度数,现在求这个度的序列能不能构成一个无向图。这个算法也是基于贪心的思想。我们每次把定点的度来排序。用最大度的顶点来向其余的顶点连边,以此类推,当所有顶点的度数都为零时就是可图化的,如果出现了负数那么就是不可图化的。bool havel(){ for(int i=0;i<n;i++){原创 2016-06-11 20:25:51 · 945 阅读 · 0 评论 -
乘法逆元与费马小定理
逆元:类似倒数和相反数的概念,具体自己百度,我也是百度的,这让我想起了离散数学中提到了左逆右逆,哎,离散没学好啊。乘法逆元:我们知道(A/B)%M=(A∗(1/B))%M(A/B)\%M=(A*(1/B))\%M。另1/B1/B等于HH,那么HH就是B关于M的乘法逆元,其实就是关于M的一个相反数,B∗H≡(1%M)B*H≡(1\%M)那么我们如何求乘法逆元呢扩展欧几里得算法费马小定理扩展欧几里原创 2016-05-17 19:54:10 · 3209 阅读 · 0 评论 -
次小生成树
Description: 次小生成树是次于最小生成树的一个生成树,也就是说存在一种大于且仅仅大于最小生成树的一种连接所有点的方式来连通一个图。 Solution: 我们知道,次小生成树可以由图中不属于最小生成树的边替换最小生成树上一条最大的边来获得。这是为什么呢。我们知道在已经生成了最小生成树的图中,添加一条不属于最小生成树的边势必会形成一个环,那么这个时候我们就要在最小生成树上删掉一条边。这样就原创 2016-03-29 11:20:24 · 556 阅读 · 0 评论 -
BM字符串匹配算法解析
BM算法相比较KMP算法较容易理解,两个算法都是字符串的匹配算法,只不过KMP是前缀匹配算法,而BM 是后缀匹配算法,KMP主要依赖next[], 而BM主要依赖bs[], gs[]也就是我们常说的坏字符和好后缀。首先说明一点,BM字符串比较算法是从模式串的末尾向前进行比较的,坏字符是当模式串与目标串比较单个字符,且目标串与模式串不匹配的那个目标串字符。那么此时模式串右边的字符已经完成匹配,这时就需原创 2017-04-06 15:28:05 · 1101 阅读 · 0 评论 -
最大子段连续积
描述:一个数组,现在让你求出这个序列的连续子序列的最大乘积,并且求出开始位置和结束位置。解决:类似最大字段连续和一样的求法,这题也可以用Dp,不过我更喜欢用普通的O(n)算法求得;最大字段连续积比最大字段连续和要复杂一点,原因就是多了一个”负负得正”,当前位置的最大积可以由当前的数(负数)乘以当前的最小值(负数)来得到一个很大的正数,所以,最大积的状态可以由最小值和最大值两个转移过来。同样,我们要原创 2017-04-06 19:22:00 · 1458 阅读 · 0 评论 -
剑指Offer66题之每日6题 - 第二天
原题链接:第一题:斐波那契数列;第二题:跳台阶;第三题:变态跳台阶;第四题:矩形覆盖;第五题:二进制中1的个数;第六题:数值的整数次方;第一题:斐波那契数列题目: 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。 n<=39。解析: 斐波拉契数列的定义: F0=0,F1=1F0...原创 2017-12-29 20:44:25 · 6591 阅读 · 4 评论 -
剑指Offer66题之每日6题 - 第五天
原题链接:第一题:复杂链表的复制;第二题:二叉搜索树与双向链表;第三题:字符串的排列;第四题:数组中出现次数超过一半的数字;第五题:最小的K个数;第六题:连续子数组的最大和;第一题:复杂链表的复制题目: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节原创 2018-01-03 23:22:35 · 18220 阅读 · 0 评论 -
剑指Offer66题之每日6题 - 第一天
原题链接:第一题:二维数组中的查找;第二题:替换空格;第三题:从尾到头打印链表;第四题:重建二叉树;第五题:用两个栈实现队列;第六题:旋转数组的最小数字;第一题:二维数组中的查找题目: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。原创 2017-12-27 17:40:16 · 5682 阅读 · 2 评论 -
剑指Offer66题之每日6题 - 第四天
原题链接:第一题:顺时针打印矩阵;第二题:包含min函数的栈;第三题:栈的压入、弹出序列;第四题:从上往下打印二叉树;第五题:二叉搜索树的后序遍历序列;第六题:二叉树中和为某一值的路径;第一题:顺时针打印矩阵题目: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。解析: 这题没什么好说的,具体看代码,考察代码的实现。class Solution {publi原创 2018-01-02 21:24:55 · 1976 阅读 · 0 评论 -
剑指Offer66题之每日6题 - 第三天
原题链接:第一题:调整数组顺序使奇数位于偶数前面;第二题:链表中倒数第k个结点;第三题:反转链表;第四题:合并两个排序的链表;第五题:树的子结构;第六题:二叉树的镜像;第一题:调整数组顺序使奇数位于偶数前面题目: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变原创 2017-12-30 22:21:54 · 2497 阅读 · 0 评论 -
完美解法的两道题
近些天看到了两道题,也做了,不断修改和完善,觉得自己这两道题的解法是最优的,不知你们同意不,如果还有更好的解法,请在评论区留言.第一题:N点共圆题目: 给你N个整数点,判断这N个是否可能在同一个圆周上.输入: 多组输入,第一行输入一个整数N(1<=N<=9),第二行输入2N个整数,表示N个(x,y)的点,-20 <=x,y<=20.而且给出点是逆时针给出,任意三点不共线。输出: 如果原创 2017-10-26 00:05:19 · 757 阅读 · 0 评论 -
用一个栈实现另一个栈的排序
背景:一个栈的排序其实是很好做的,但是现在要你将该栈从顶到底从大到小排序,只允许申请一个辅助栈,可以申请有限个变量,除此之外不能再申请额外的数据结构,你该怎么搞?算法:设要排序的栈为st,辅助栈为help,从st弹出的元素记为cur,help的栈顶元素记为top。如果cur小于或等于top,则将cur压入help;如果cur大于top,则将help中的元素逐一弹出并压入st,直到cur小于等于原创 2017-10-30 02:10:45 · 519 阅读 · 0 评论 -
求无向图中的三元环个数
无向图是个稀疏图,点数n<105n<10^5, 边数m<min(105,n∗(n−1)2)m<min(10^5, \frac{n*(n - 1)}{2}).现在给出n,m,E(边的集合)n, m,E(边的集合)。求出这个无向图中三元环的个数,两个三元环不同是:当对于两个三元环的边,某个三元环存在一条边在另一个三元环的边中无法找到!首先想到的方法只能是暴力求解,很直接的暴力就是枚举每一条边,以一条边度原创 2017-04-16 14:36:47 · 6992 阅读 · 6 评论 -
右移一位和除二的区别
首先看一下下面这个代码,然后判断两个结果是一样的吗#include &lt;bits/stdc++.h&gt;using namespace std;int main(){ for (int n; EOF != scanf("%d", &amp;n); ) { printf("&gt;&gt; 1 : %d\n",原创 2018-09-07 13:40:52 · 25885 阅读 · 3 评论