校招常考算法
dota爱好者
略
展开
-
后缀树系列二:线性时间内构建后缀树(包含代码实现)
上一篇文章已经介绍了后缀树的前前后后的知识,并且采用各种技巧逼近线性时间了,至于具体怎么操作大家看完之后应该多多少少有点想法了。而之所以将本文跟上一篇文章分开,主要考虑有三:第一,和在一起文章就会太长了,看的头疼。第二,理论跟实现本来就有差异,本文中一些具体实现并没有严格遵守上文中的条条框框。当然了,主题思想是一样的。第三,本文会从具体实现的角度,在实现过程中进一步阐述上文中的原理。换个角转载 2016-03-20 11:18:07 · 1394 阅读 · 0 评论 -
主元素问题求解
1,主元素问题描述:即在数组中出现次数大于总数一半的元素。2,当数组元素之间可以有序时用求中位数的方法解决,因为若存在主元素,那么它一定会在中位数上出现。中位数:数列排序后位于最中间的那个数,如果一个数列有主元素,那么必然是中位数。求一个数列有没有主元素,只要看中位数是不是主元素。所以难点在求中位数上,如果使用排序算法后,自然可以求得中位数,但一般时间复杂度为O(nlogn);原创 2015-10-27 12:09:23 · 4111 阅读 · 0 评论 -
从左到右升序,从上到下升序的元素互异的二维数组元素查找问题
1.问题定义:什么叫做从左到右升序,从上到下升序的元素互异的二维数组元素查找问题?即在每一行上递增,在每一列上也递增的互异的二维数组上查找一个元素是否在该二维数组上。右图即是一个这样的二维数组:2.解决方法。(1)很容易想到的就是遍历一遍,时间复杂度为O(n2);(2)就是在每一行上做一个二分查找,总共n行,时间复杂度为O(nlogn);(3)就是从对角线角度出发,总共原创 2015-10-28 22:04:57 · 1751 阅读 · 0 评论 -
动态规划解最长公共子序列问题
转载地址:http://blog.csdn.net/yysdsyl/article/details/4226630动态规划法经常会遇到复杂问题不能简单地分解成几个子问题,而会分解出一系列的子问题。简单地采用把大问题分解成子问题,并综合子问题的解导出大问题的解的方法,问题求解耗时会按问题规模呈幂级数增加。为了节约重复求相同子问题的时间,引入一个数组,不管它们是否对最终解有转载 2015-11-04 10:58:50 · 629 阅读 · 0 评论 -
动态规划求最长递增子序列(longest increasing subsequence)
1,什么是动态规划?在现实生活中,有一类活动的过程,由于它的特殊性,可将过程分成若干个互相联系的阶段,在它的每一阶段都需要作出决策,从而使整个过程达到最好的活动效果。当然,各个阶段决策的选取不是任意确定的,它依赖于当前面临的状态,又影响以后的发展,当各个阶段决策确定后,就组成一个决策序列,因而也就确定了整个过程的一条活动路线,这种把一个问题看作是一个前后关联具有链状结构的多阶段过程就称为多阶段原创 2015-11-04 22:00:28 · 6171 阅读 · 0 评论 -
二叉搜索树(二叉排序树,二叉查找树,二叉检索树)的查找,插入,删除
1,二叉搜索树定义?(1)每个节点有一个唯一的key值,且所有结点互不相同;(2)左子树所有key值小于根的key值;(3)右子树所有key值大于根的key值;(4)左右子树都是二叉搜索树。这就是一棵二叉搜索树。2,二叉搜索树的查找操作:(1)与根结点的key值比较,相等则 查找成功;(2)小于则查找左子树;(3)大于则查找右子树。3,二原创 2015-11-13 17:28:51 · 3565 阅读 · 0 评论 -
一步一步写平衡二叉树(AVL树)
转载:http://www.cppblog.com/cxiaojia/archive/2012/08/20/187776.html平衡二叉树(Balanced Binary Tree)是二叉查找树的一个进化体,也是第一个引入平衡概念的二叉树。1962年,G.M. Adelson-Velsky 和 E.M. Landis发明了这棵树,所以它又叫AVL树。平衡二叉树要求对于每一转载 2015-11-13 22:27:13 · 813 阅读 · 6 评论 -
平衡二叉树(AVL树)的查找,插入和删除
1,http://blog.csdn.net/zzuchengming/article/details/49824561这是我转载的一个讲解AVL树的文章,思路很好,内容也很清晰,这里基础知识不再赘述!2,下边是我参考这篇文章写的代码,发现了其中的一个小错误!#include "stdafx.h"#include using std::cin;using std::cout;usi原创 2015-11-15 22:41:27 · 1412 阅读 · 1 评论 -
对红黑树的一些理解
1,红黑树(RBT)的定义:它或者是一颗空树,或者是具有一下性质的二叉查找树:1.节点非红即黑。2.根节点是黑色。3.所有NULL结点称为叶子节点,且认为颜色为黑。4.所有红节点的子节点都为黑色。5.从任一节点到其叶子节点的所有路径上都包含相同数目的黑节点。2,如何理解和记忆这5个定义?称为“红黑树”,即节点非红即黑,给节点着色的目的原创 2015-11-18 20:17:29 · 2358 阅读 · 0 评论 -
最大子数组(最大连续区间和)问题
1,应用背景:最大子数组的问题可以用到股票市场,比如想得知在一段时间内怎么让股票买进卖出后的利益最大。就可以转化为最大子数组问题。2,解决方法:(1)暴力枚举法,O(n3)#include "stdafx.h"#include #include #includeusing namespace std;//暴力枚举法,O(n^3)#define AFFINITY -65原创 2015-10-22 22:17:30 · 3156 阅读 · 0 评论 -
剑指offer面试题3之二维数组中的查找
问题描述:在一个二维数组中,每一行都从左到右递增,每一列从上到下都是递增,给定一二维数组和整数值,问该值在该二维数组中吗?1,考虑问题时需要注意:我们不能想当然的认为它是一个n方矩阵,即它的列数和行数不一定相同。2,除了暴力枚举o(n2)。肯定还有其他方法:在牛客网上编码为:class Solution {public: bool Find(vector > ar原创 2016-03-16 21:38:52 · 591 阅读 · 0 评论 -
剑指offer面试题之从头到尾打印链表
1.问题:输入一个链表,从尾到头打印链表每个节点的值。 2,思考:(1),笨方法:从头到尾扫描一遍,改变next指针,变成逆向。再扫描一遍改变后的链表,把值放入一个vector中,返回。(2),既然是从尾到头输出,即逆序输出,即从底到上输出,而递归恰好有自底至上的性质,适应这里。3,在牛客网上的编码为:/*** struct ListNode {*原创 2016-03-20 16:10:44 · 705 阅读 · 0 评论 -
剑指offer面试题之用两个栈实现队列
1,问题:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。2,想法:(1),初始想法:push时,就用stack1进栈;Pop时,先把stack1的值出栈,同时入栈stack2,然后再去stack2栈顶元素,再出栈。再把stack2中元素出栈,同时入栈stack1,即回到Pop前状态!(2),在(1)的基础上有个改进点,那就是当sta原创 2016-03-20 16:37:10 · 352 阅读 · 0 评论 -
宝典练习1之在排序数组中找指定元素出现次数
分析题目:首先想到的是遍历一遍数组,遇到相同元素就加1,遍历完之后就知道有多少个这样的元素,时间代价为o(n)!但题目中有表示为排序数组,应该有更加简易的方法,容易想到的是二分查找,因为有序!但有一个问题就是,当找到有元素和查找数据相等时,仍然需要继续查找,那具体是往左还是往右呢?得分情况:要求查找数据的个数,而且数组有序,那么我们求出该数在数组中出现的最左位置和最右位置,再进行算原创 2016-03-07 10:44:20 · 443 阅读 · 0 评论 -
宝典练习2之求两个数组的交集
分析问题:1,最容易想到的是暴力枚举法,即拿A数组中的元素一个个去B数组中遍历,有相等的即为交集元素,假设A数组长为m,B数组为n,那时间代价为O(mn)!2,一种有预处理的方法:先对两个数组进行排序处理,一般代价为O(n)到O(logn)了。然后对两个已经有序的数组求交集。对两个数组分别设置下标i,j,从零开始遍历,若碰到相等的,i和j同时加1,该元素并入交集,若A【i】大于B【原创 2016-03-07 15:14:30 · 460 阅读 · 0 评论 -
求最长公共子序列
根据前边转载他人的文章,自己写了一遍:#include "stdafx.h"#include using namespace std;void lcs(char *a, char *b, int m, int n, int **c, int **s){ if (m == 0 || n == 0 || a == NULL || b == NULL ) { return; }原创 2016-03-07 22:06:04 · 354 阅读 · 0 评论 -
剑指offer面试题1之赋值运算符函数
//要写一个赋值运算符函数,即重载赋值运算符,有两种形式:类成员函数和友元函数;我们这里用类成员函数的形式#pragma onceclass CMyString{public: //CMyString(void);//这个构造函数和CMyString(char* pdata = NULL)一定程度上重定义了,当定义 //CMyString类型对象时原创 2016-03-16 12:45:55 · 546 阅读 · 1 评论 -
剑指offer面试题6之前序中序建立二叉树
1,这是在vs2008上编写的代码。Bnode.h#pragma onceclass Bnode{public: Bnode(void); ~Bnode(void); Bnode(int x, Bnode* y, Bnode* z); Bnode* construct(int *Pre, int sP, int eP, int *In,int sI, int eI);pr原创 2016-03-16 16:13:29 · 297 阅读 · 0 评论 -
剑指offer面试题11之求数值的整数次方
1,在vs2008上的代码为:// 数值的整数次方.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include #include using namespace std;bool iscorrectinput = true;bool equal(double a, double b){ if ((a - b > -1e-15) &&原创 2016-03-16 19:04:19 · 352 阅读 · 0 评论 -
多路查找树开篇
转载地址:http://blog.csdn.net/dazhong159/article/details/79642451、引言 以前我们所讨论的数据结构,处理数据都是在内存中。假如我们所要操作的数据集非常大,大到内存无法处理了怎么办?如数据库上千万记录的数据表、硬盘中上万个文件等。在这种情况下,对数据的处理需要不断的从硬盘等存储设备中调入或者调出内存页面。而过多转载 2015-11-19 15:19:07 · 909 阅读 · 1 评论 -
B树到B+树再到B*树
一,有一点,再次强调下:B-树,即为B树。因为B树的原英文名称为B-tree,而国内很多人喜欢把B-tree译作B-树,其实,这是个非常不好的直译,很容易让人产生误解。如人们可能会以为B-树是一种树,而B树又是一种树。而事实上是,B-tree就是指的B树!二,B树!B树是为了减少磁盘IO操作或为了其它存储设备而设计的多路平衡查找树。与之前介绍的红黑树很相似,但在降低磁盘I/0操作方面要更好原创 2015-11-19 17:03:36 · 370 阅读 · 0 评论 -
Bellman-Ford求图的单源最短路径
1,Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的。这时候,就需要使用其他的算法来求解最短路径,Bellman-Ford算法就是其中最常用的一个。该算法由美国数学家理查德•贝尔曼(Richard Bellman, 动态规划的提出者)和小莱斯特•福特(Lester Ford)发明原创 2015-11-24 21:08:00 · 648 阅读 · 0 评论 -
2路插入排序实现
1,2路插入排序的思想:在折半插入排序的基础上改进,目的是减少排序过程中激动记录的次数,既然是在折半的基础上,那么应该也能减少查找操作。具体做法:另设一个和原数组L同类型的数组D,将L[1]赋值给D[0],并将D[0]看成是在排好序的序列中处于中间的位置,即当L中来一个数和D[0]比较,大往D[0]后放,小往前放,这时候把D看成是个循环向量。因为在以D[0]分隔的两边都是有序序列,我们原创 2015-09-24 10:23:25 · 972 阅读 · 0 评论 -
Kruskal算法求最小生成树
1.Kruskal的思想是:先把n个顶点分成n个单独的连通分量,把边用堆排序或者别的排序排成非递减序列;一次从中拿出最小的边,判断是不是连接两个不同的连通分量,若是,则该边是一个最小生成树的边,否则往下找次小的边,继续,直至找到n-1条边为止。难点:怎么判断一条边是不是连接两个不同的连通分量,在网上看了一些资料,大多是用并查集来实现。具体为:(1)维持一个father【】数组,原创 2015-10-16 09:05:47 · 1028 阅读 · 0 评论 -
Prim实现最小生成树
1,什么是最小生成树?用连通网(图)表示n个城市以及n个城市间可能设置的通信线路,其中网的顶点表示城市,边表示两城市之间的线路,带有权值。对于这样的一个连通网,找n-1条边使得这n个城市连通,这就是一颗生成树,这样的生成树很多,我们要找总的权值最小的树,即为最小生成树。2,应用背景?在n个城市间建立耗费经费最小的通信网。3,存在方法:Prim和Kruskal方法;主要利用了简称为M原创 2015-10-14 22:39:23 · 673 阅读 · 0 评论 -
分别使用Kahn和DFS实现拓扑排序
1,先了解什么是偏序?偏序就是图中存在无先后顺序的顶点对。全序即找不到这样的顶点对。2,什么是拓扑排序?把图由偏序变成全序的操作即是拓扑排序。前提是有向无环图,拓扑才能成功。3,Kahn算法思想:先把入度为0的点入栈,每次从中出栈一个顶点,删除从它出发的边,相应顶点的入度减少1,若有入度为0的点,则入栈,重复至栈为空。4,DFS思想:前提是有向无环图,因为最先完成DFS的顶点恰原创 2015-10-12 22:43:35 · 930 阅读 · 0 评论 -
外部排序技术之多路归并
转载地址:http://blog.chinaunix.net/uid-25324849-id-2182916.html外部排序技术之多路归并重点:败者树的创建调整函数1.外部排序概述外部排序指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序整个文件的目的。外部排序最常用的算法是转载 2015-10-12 09:24:24 · 566 阅读 · 0 评论 -
Trie树和后缀树讲解及应用
后缀数组原理及应用详解 在pongba的讨论组上看到一道Amazon的面试题:找出给定字符串里的最长回文。例子:输入XMADAMYX。则输出MADAM。这道题的流行解法是用后缀树(Suffix Tree)。这坨数据结构最酷的地方是用它能高效解决一大票复杂的字符串编程问题: 1.在文本T里查询T是否包含子串P(复杂度同流行的KMP相当)。2.文本T里找出最长重复子串。比如转载 2015-09-26 22:03:53 · 1942 阅读 · 0 评论 -
求强连通分量的双DFS,Tarjan和Gobow算法详解
1.强连通分量-----双DFS算法思想:对一个有向图作两遍DFS,第一遍DFS能确定图中每个顶点的DFS完成时间,第二遍DFS从第一遍DFS完成时间的逆序开始遍历,这时得到的一棵棵深度优先搜索树就是一个个对应的强连通分量。举例:对于下面这个有向图,我们以C为源节点进行第一遍DFS,可以得到每一个顶点的 (访问时间/完成时间).也就是我们能得到顶点DFS完成时间,逆序为:b->e-原创 2015-03-25 09:46:41 · 1983 阅读 · 3 评论 -
双DFS求强连通分量
用双DFS实现强连通分量是3个方法中比较好理解的。注意事项:1.读入文件时,我用是fstream,流的方式读入!2.如果是数据集中没有别的多余符号,可以直接读入。若是由逗号等符号分隔开,我用的是CString中的readstring来按行读入,需引入头文件.在按行截取,用到find()函数,TrimLeft()和TrimRight()函数!3.按行读入数据后建立正反两个邻接表!按头插法建立效率更高原创 2015-07-07 20:43:43 · 1619 阅读 · 0 评论 -
堆以及堆排序实现
1.今天实现了一下堆排序,这里的堆是指二叉堆,至于二项堆和斐波那契堆以后再说。先看二叉堆的定义:二叉堆是完全二叉树或近似完全二叉树。满足特性是:父亲节点的值大于等于(小于等于)左右孩子的值,并且左右子树也是二叉堆。对应的二叉堆是大顶堆(小顶堆)。二叉堆是完全二叉树,可以用线性表来存储。2.实现堆排序时的想法:(1)一个关键点是堆的调整,调整的时候一定要注意先找到左右孩子中较...原创 2015-09-22 11:41:23 · 609 阅读 · 0 评论 -
静态链表实现
1,有些高级语言中没有“指针”数据类型,只能用数组来模拟线性链表的结构,数组元素中的指针“域”存放的不是元素在内存中的真实地址,而是在数组中的位置。这样的链表称为静态链表。2,静态链表是用数组实现的,是顺序的存储结构,在物理地址上是连续的,而且需要预先分配大小。动态链表是用申请内存函数(C是malloc,C++是new)动态申请内存的,所以在链表的长度上没有限制。动态链表因为是动态原创 2015-09-06 14:18:16 · 1208 阅读 · 0 评论 -
栈的基本操作
1. 栈的定义栈是一种特殊的线性表。其特殊性在于限定插入和删除数据元素的操作只能在线性表的一端进行。如下所示:结论:后进先出(Last In First Out),简称为LIFO线性表。栈的基本运算有六种:构造空栈:InitStack(SqStack &S)判栈空: StackEmpty(SqStack S)判栈满: Stack原创 2015-11-26 21:26:12 · 804 阅读 · 0 评论 -
汉诺塔问题
1,(n阶汉诺塔问题)假设有3个分别命名为X,Y和Z的塔座,在塔座X上插有n个直径大小各不相同,依照大小编号为1,2,...,n的圆盘。现在要求将X塔座上的圆盘移动到Z他坐上并按同样顺序叠排,圆盘移动时必须遵循下来规则:(1)每次只能移动一个圆盘;(2)圆盘可以插在X,Y,Z中的任意一个;(3)任何时刻都不能将一个大圆盘压在小圆盘上。看如何移动?2,当n=1时很简单,只要将1号原创 2015-11-26 21:51:14 · 2319 阅读 · 0 评论 -
简单选择排序
1,思路:选择排序是固定位置找元素,(插入排序是固定元素找位置)。比如要找最小的元素,即0号位置元素,就要先找出数组的最小元素,和0号元素互换;接着找次小的元素就是从剩下的length-1个元素里找最小的元素然后和1号位置元素互换,直到所有位置元素都确定为止。2,简单代码#include "stdafx.h"#include #include using namespace原创 2015-12-05 21:45:10 · 519 阅读 · 0 评论 -
各种内部排序算法复杂度的比较和排序方法的选择
转载地址:http://blog.chinaunix.net/uid-26565142-id-3126683.html选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法, 冒泡排序、插入排序、归并排序和基数排序是稳定的排序算法。冒泡法: 这是最原始,也是众所周知的最慢的算法了。他的名字的由来因为它的工作看来象是冒泡: 复杂度为O(n*n)。当数据为正序,将不会有转载 2015-12-04 19:47:49 · 525 阅读 · 0 评论 -
有向无环图求单源最短路径问题
1,有向无环图可以用拓扑排序先求得拓扑序列;对于得到的拓扑序列,我们遍历一遍,对于每一个元素,我们看它的邻接边,(因为拓扑序列中当前元素只可能存在指向在它之后的元素的边),对它的邻接边做松弛操作,这样一遍过后,就得到了给定源节点的单源最短路径!2,时间复杂度分析:拓扑排序的时间复杂度为O(n+e),遍历一遍拓扑序列,以及松弛操作的代价为O(n+e);所以总的时间代价为O(n+e).3,原创 2015-11-28 22:20:36 · 1654 阅读 · 0 评论 -
队列的基本操作
队列特性:先进先出(FIFO)——先进队列的元素先出队列。来源于我们生活中的队列(先排队的先办完事)。队列有下面几个操作:InitQueue() 初始化队列EnQueue() 进队列DeQueue() 出队列QueLength( ) 队列元素个数 DestroyQueue( ) 销毁队列队列可以由数组和链表两种形式原创 2015-11-28 11:59:12 · 1303 阅读 · 1 评论 -
直接插入排序和折半插入实现
1,初写的代码,浪费了空间#include "stdafx.h"#include#include#includeusing namespace std;int _tmain(int argc, _TCHAR* argv[])//缺陷:浪费了空间!{ cout> num; int *a = new int[num]; srand(time(0)); for(in原创 2015-08-26 17:10:37 · 787 阅读 · 0 评论 -
快速排序实现和改善
1,快速排序的一个关键是找枢轴,我的处理方式是将起始位置和中间位置以及最后位置的值进行比较取中间值,如果枢轴不在起始位置可以交换后统一只考虑枢轴在起始位置时的处理方式,因为枢轴不同,处理方式有点小差异。2,另一改善点是如果有和枢轴相等的数据,在一次快排后应该和枢轴放一起,这样下一次快排的规模会变小,这在数据集中有很多相同数据时很有用。处理方式是在遍历过程中遇到比枢轴大和小的数据还是交换,遇到相...原创 2015-09-01 09:10:23 · 827 阅读 · 0 评论