
算法
文章平均质量分 72
hitrose27
熟男
展开
-
Trie树/字典树
传说中字典树能够有效地压缩数据存储量,不明就里,查阅一番。字典树在百度百科中的定义都说效率高那就效率高吧……高效率我是可以理解的,毕竟查找的次数减少了非常多,但是对于节省内存这一项实在想不通,于是用了一个大小为2.137MB(去除换行符1.7067MB,一共19,9071个词条)的字典文件作为输入进行了测试,结果如下:There are 451798 nodes and need 48794184 bits to store!平均每个词条需要2.27个节点,每个词条的平均长度为8.99个字符(减掉了行尾的换原创 2011-03-18 22:04:00 · 739 阅读 · 0 评论 -
FFT
FFT直接的目的是两个多项式相乘,众所周知两个长度为n的多项式相乘, 一般性算法需要的时间复杂度是O(n^2)。而FFT算法则把多项式相乘的 时间复杂度降到了O(n log n),当n比较大时,性能上的差异是相当明显的, 尤其是对于音频信号的处理,n一般都在几万到几百万。 要了解FFT算法,首先需要了解多项式的表示。 我们一般表示一个多项式都是按照多项式的系数: y = anX^n+a(n-1)X转载 2012-06-09 15:28:53 · 1504 阅读 · 0 评论 -
编程之美--发帖水王及扩展问题
重点是理解:当有一半都是同一个ID时,同时删除两个ID得到的结果最大ID已然占一半以上。 剩下的在代码中有些注释,贴之: //This file is used to test the size of //different char type#include using namespace std;int FindMost(int *iVec,int n){ int原创 2011-04-05 15:24:00 · 1053 阅读 · 0 评论 -
编程之美--数组中的最长递增子序列(LIS longest increasement sequence)
最早见到这道题目是在poj中,具体的题目忘记了,但是所要求的算法是一致的。 当时在学习LCS,因此想了一种和LCS比较相似的解法: 对原数组使用快速排序,然后使用LCS的思想求最大公共字串。 这种解法比较容易理解,但是所需要的空间为:O(2N) = O(N);时间为O(N^2+N*lgN) = O(N^2),显然这不是一种最优的解法。但是当时还真没有想到更好的解法…… 最近原创 2011-04-05 13:37:00 · 1110 阅读 · 0 评论 -
二叉树转换为树和树林的方法
传送门二叉树转换为树和树林的方法:如果y是x的父亲,且x是y的左子,则把x的右子,x右子的右子…和y相连;去除父亲和右子之间的连线;树转换为二叉树:连接所有的兄弟节点;对于每一个父亲节点,只保留其和其长子之间的连线;某二叉树结点的对称序序列为A、B、C、D、E、F、G,后序序列为B、D、C、A、F、G、E。该二叉树结点的前序序列为 (2)1. E、G原创 2011-10-12 21:23:20 · 3394 阅读 · 0 评论 -
编程之美——2.7最大公约数
这里提供了一种高效的解决方法,值得借鉴。 需要注意的是程序GCD函数的第二行,当其中一个值为0的时候返回另外一个值,否则导致栈溢出(因为没有非递归的结束条件!) 代码如下: //编程之美2.7 最大公约数#include using namespace std;templateT Gcd(T x, T y){ if(x<y) return Gcd(y,x);原创 2011-04-02 13:22:00 · 868 阅读 · 0 评论 -
最小编辑距离及其C++实现
一、问题介绍:本题提出了一些关于将字符串x[1..m]转换成y[1..n]的操作。这些操作有复制、替代、删除、插入、互换和终止。这些操作所需的开销是不同的,但每个操作的开销都可以看是一个我们已经的常量,我们假设复制和替代这类操作的开销要比插入和删除这类操作的开销少。我们用x[1..m]来保存原字符串,数组下标用i表示,初始化为1;用y[1..n]来保存转换后的字符串,数组下标用原创 2010-09-01 08:51:00 · 3833 阅读 · 0 评论 -
编程之美--寻找满足条件的两个数
复习了快速排序。 另外还有一个比较大的收获是:对于返回两个下标的题目,使用先排序,再用两个游标分别从数组的两端进行遍历的方法可以达到O(N)的时间复杂度。 本题的主要思路就沿着这个想法展开,代码如下: //编程之美,快速寻找满足条件的两个数字#include using namespace std;bool FindTwoNumber(int *iArray, in原创 2011-04-05 15:44:00 · 1129 阅读 · 0 评论 -
如何不用库函数实现根号的求值
今天和朋友聊面经,说到一道题目,如何不用库函数求根号,并且能用函数的输入参数来控制误差,他想了一个比较牛逼的方法,小数转整数,然后二分查找。在那么短的时间想到这个地步真是不错,但是我貌似记得科学计算的课上说过类似的东西,用泰勒计算:其实想到了这个其他的都比较简单了,贴一下代码:#include #include using namespace std;#define _DEBUG/原创 2011-03-19 00:36:00 · 3110 阅读 · 0 评论 -
top coder试玩心得
做人要有点自知之明,自己确实不是有talent的coder,于是乎,自娱自乐吧。。。550分的这一题,题目如下:Problem Statement In most states, gamblers can choose from a wide variety of different lottery games. The rules of a原创 2012-11-29 16:14:51 · 1341 阅读 · 2 评论 -
实现单链表的对称判定算法
在Y公司的笔试题中遇见了这样一个题目:一个单链表,如何使用O(1)的空间复杂度判定其是否为对称链表,例如A->B->C->T->C->B->A就是一个对称链表。首先最自然的就能想到N^2的算法:查找1号和最后一个是否相同,再查找2号和倒数第二个。。。查找i和N-i是否相同。但是这个算法明显不是最优解答。对链表的分析之后可以看出,如果找到中间节点,从中间节点断开链表,原创 2011-10-18 10:53:11 · 2823 阅读 · 0 评论 -
编程之美--区间重合判断(并查集求解)
题目大意:输入两个表示区间范围的整数[x,y]然后输入N个无序区间[x1,y1], [x2, y2], [x3, y3]...求解第一次输入的区间是否在N个无序区间组合成的大区间中。我的思路是使用并查集的方法:1. 保存原始范围2. 对每输入的一个区间使用并查集的方法--i从xi到yi做并查集的插入MakeSet(FindSet(xi),FindSet(i));3. 输入结束之后通过比较x和y的根是否相同即可。代码如下://区间重合判断,并查集求解//这种求解需要假定输入整数的范围//在这里假定n原创 2011-04-15 23:00:00 · 2107 阅读 · 0 评论 -
红黑树C++实现
看算法导论看的有点晕,代码的缩进让我直接抓狂了,网上找了一个比较靠谱的解法,链接现在具体分析一下插入操作:1. 首先父亲节点如果是黑色节点的话,不需要处理了,多一个红色节点不会有任何影响.2. 如果父亲节点是红色的,而叔父节点也是红色,那就是把父亲和叔父节点同时改成黑色,祖父改为红色,然后递归的向上传递.3. 如果父亲节点是红色的,而叔父节点是黑色的. 后面的话比较拗口.父亲是祖父的左孩子. (1)如果自己是父亲的左孩子,那么修改父亲为黑色,祖父为红色,然后右转祖父 (2)如原创 2011-03-21 15:07:00 · 939 阅读 · 0 评论 -
Hash算法
<br />字符串hash算法比较<br />字符串的算法一般大公司都会考到,我们首先要想到高效的hash。如百度查找一组字符串是否出现在某个文本中,这个不是考什么kmp,他们想听到的是hash。趋势科技考的是从某个文本中删除一组字符串,我想也是要hash吧。<br />1 概述<br /> 链表查找的时间效率为O(N),二分法为log2N,B+ Tree为log2N,但Hash链表查找的时间效率为O(1)。<br />设计高效算法往往需要使用Hash链表,常数级的查找速度是任何别的转载 2011-03-25 09:35:00 · 602 阅读 · 0 评论 -
编程之美--整数中1的个数
<br />从简单到复杂的分析,从1位数开始,找到规律,抽象出公式。<br />体现的是分解问题的能力,找到问题切入点的能力。<br />个人觉得书中的公式有一点问题,对于命题2的公式应该为f( 10^n - 1) = n * (10^ (n-1) )<br /> <br />代码:<br />//编程之美--求1的个数//如果要求f(N) = N的最大解N,先证明//f( 10^n - 1) = n * (10^ (n-1) )#include <iostream>using namesp原创 2011-03-29 10:35:00 · 701 阅读 · 0 评论 -
海量数据中寻找中位数
<br />题目:在一个文件中有 10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。只写出思路即可(内存限制为 2G的意思就是,可以使用2G的空间来运行程序,而不考虑这台机器上的其他软件的占用内存)。 <br /><br />关于中位数:数据排序后,位置在最中间的数值。即将数据分成两部分,一部分大于该数值,一部分小于该数值。中位数的位置:当样本数为奇数时,中位数=(N+1)/2 ; 当样本数为偶数时,中位数为N/2与1+N/2的均值(那么10G个数的中位数,就第5G大的数与第5G+1大转载 2011-03-29 22:35:00 · 1185 阅读 · 0 评论 -
编程之美--寻找K大数
<br />树中最远的节点个数一定是两个叶子节点或者叶子节点到根节点的距离(该树只有一个叶子节点的情况!)。<br /> <br />解法5:用O(4*n)的方法对原数组建最大堆,然后pop出k次即可。时间复杂度为O(4*n + k*logn)<br /> <br />解法7:利用hash保存数组中元素Si出现的次数,利用计数排序的思想,线性从大到小扫描过程中,前面有k-1个数则为第k大数,平均情况下时间复杂度O(n)<br /> <br />附注:<br /> 1. STL中可以用n转载 2011-03-29 22:34:00 · 864 阅读 · 0 评论 -
求解树中的节点和为所求值的所有路径
<br />笔试的时候碰见一个问题,当时没有解决,回来想了一下,其实也很简单……<br /> <br />题目要求:已知一颗树(二叉排序树),现在要求求解路径和为固定值的所有路径。<br /> <br />例如树:<br /> 10<br /> 5 12<br /> 4 7<br /> <br />所求的和为22,则输出的路径为10 5 7 以及10 12。<br /> <br />这原创 2011-04-02 13:28:00 · 903 阅读 · 0 评论 -
编程之美--数组循环移位
<br />面试的时候也碰见了这个问题,我当时采取的解决方案是把数组double,然后从length-k开始遍历length个字符。时间开销是O(2N) = O(N)<br />空间开销是O(2N) = O(N);<br />这个代码就不贴了,实现起来比较简单。<br /> <br />为了减少时间和空间的开销,我们还能有更好的解法么?<br />时间复杂度已经是线性了,这个开销已经不能再降低了,空间呢?<br /> <br />然后我考虑用大小为k的数组保存需要移位的数据,然后执行移位操作。考虑到当k>N原创 2011-04-03 10:32:00 · 905 阅读 · 0 评论 -
Bloom Filter
<br />以下内容摘自:链接<br /> <br /> <br />Bloom Filter是一种空间效率很高的随机数据结构,它利用位数组很简洁地表示一个集合,并能判断一个元素是否属于这个集合。Bloom Filter的这种高效是有一定代价的:在判断一个元素是否属于某个集合时,有可能会把不属于这个集合的元素误认为属于这个集合(false positive)。因此,Bloom Filter不适合那些“零错误”的应用场合。而在能容忍低错误率的应用场合下,Bloom Filter通过极少的错误换取了存储空间的极转载 2011-04-05 14:52:00 · 1245 阅读 · 0 评论 -
编程之美--求子数组之和的最大值
<br />编程之美和编程珠玑上面都有这个经典的例子,珠玑甚至用了第八章整整一章来阐述这个例子,这里对算法的细节就不加以阐述了,(我可以肯定没有这两本书中解释的清楚……),但是我对编程之美的扩展问题进行了求解(珠玑的题目比较深奥,还没有深入解答)。<br /> <br />在这里先说扩展问题的第二题:<br />这里以最后一种算法为基础进行扩展,每次当A[i] > nStart + A[i]时,也就是nStart大于零的时候更新数组的起始index,并且最后输出的起始index应该为该值减一(可以想一想为什原创 2011-04-06 14:23:00 · 979 阅读 · 0 评论 -
二叉树分层遍历(递归以及非递归的实现)
树的遍历是比较基本的数据结构操作方法,中序遍历、线序遍历和后续遍历什么的基本上递归一下,三行代码就能搞定。但是,树的按层遍历就会稍微复杂一些。主要思想是使用栈暂存数据,一个栈用于保存当前层的节点,另外一个栈用于保存下一层的节点,在遍历该层时,将下一层的所有节点都存储到栈中,在下一次遍历中使用。思路比较清楚,贴下这种思路的代码。void printTreeLevel(Node *原创 2013-06-14 15:29:27 · 1296 阅读 · 0 评论