
算法
lxmky
这个作者很懒,什么都没留下…
展开
-
字符串转移问题
问题:函数将字符串中的字符'*'移到串的前部分,前面的非'*'字符后移,但不能改变非'*'分析:由于问题的特殊性,我们可以直接将字符往后移,那么前面的位置全部用'*'填充,具体代码如下:#include #include using namespace std;/* * 这个方法将'*'往前移 */int change1(char *str){ int i,原创 2012-08-31 00:33:33 · 1216 阅读 · 0 评论 -
加法运算
题目:写一个函数,求两个整数的之和,要求在函数体内不得使用+、-、×、÷。分析:由于不能使用四则运算,我们可以考虑使用其他的操作,考虑是用位操作,来模拟加法操作,首先不考虑进位,使用异或操作,然后再考虑进位,使用与操作,再将进位与异或的结果进行相加,由此循环,进位为0停止。算法代码如下:#include #include #include using namespac原创 2012-08-26 09:57:16 · 795 阅读 · 0 评论 -
颠倒栈
问题:用递归颠倒一个栈。例如输入栈{1, 2, 3, 4, 5},1在栈顶。颠倒之后的栈为{5, 4, 3, 2, 1},5处在栈顶。分析:问题很简单,可以直接使用两个堆栈就行,一个pop,一个push,这样就颠倒了,但是如果加强问题,不能使用另一个栈,我们可以考虑使用递归调用(实际上递归调用也用到了栈,只是在程序调用时用到的)。程序执行分为两部分:1,reverse_stack,原创 2012-08-26 13:04:16 · 992 阅读 · 0 评论 -
尾序列问题
问题:在《编程珠玑》一书中,提到字符串旋转问题,比如有字符串ab旋转得到字符串ba,那么可以通过(a'b')'得到,其中“ ' ”表示整个字符串旋转。在这个问题中,比如"abace"通过在不同位置旋转,可以得到"eabac","ceaba","aceab","bacea",将这些字符串按照字典排序,得到:abaceaceabbaceaceabaeabac这样得到尾序原创 2012-09-05 11:19:46 · 1608 阅读 · 0 评论 -
O(n)时间的排序
问题:某公司有几万名员工,请完成一个时间复杂度为O(n)的算法对该公司员工的年龄作排序,可使用O(1)的辅助空间。分析:《算法导论》中提到,所有基于比较排序的算法,时间复杂度最低为O(nlogn),所以不能采用普通的比较排序(堆排,快排等),采用计数排序或者基数排序,桶排等。我们采用计数排序,统计一个区间内所有数字出现的次数(这是由问题的特殊性决定的),然后再输出到数组中。算法原创 2012-08-25 12:08:30 · 5267 阅读 · 0 评论 -
求解1-10000区间内的素数
问题:求出所有1-MAX之间的素数分析:我们知道如何判断一个数是否为素数,判断number是否可以被1到sqrt(num)之间数整除,如果存在被整除的,不是素数,否则就是素数。但是,如果用这种方法来计算,时间复杂度会非常高,我们采用另一种更好的方法——筛选法。筛选法直观上比较好理解,从2开始,删除所有2*p(p>=2),然后再选取下一次没有被删除的数t,同样删除t*p(p>=2原创 2012-08-27 21:52:24 · 5142 阅读 · 1 评论 -
蓄水池抽样问题
题目:微软电面问到的问题,前面提了一大堆背景,最后归结为一个问题,如何在连续的网络流量中,等概率随机抽取1个数据包。分析:参加电面时,还没看过蓄水池抽样问题,后来回来一搜,这就是典型的蓄水池抽样问题,不过当时自己也想到了一种解法,使用一个变量保存数据包,从1到i个数据包,每次遇到第i个数据包,以1/i的概率选取这个数据包,并且替换原来的数据包,这样到第n个数据包,我们能保证我们以1/n原创 2012-09-06 16:02:17 · 3224 阅读 · 0 评论 -
寻找丑数
题目:我们称只包含因子2,3,5的数为丑数,比如9,但是14不是,因为包含因子7。我们要求找到前1500个丑数。分析:直观的方法就是穷举1,2,3...n,每次得到一个数,我们穷举它的因子2,3,5,穷除这些因子后,数最后只剩1,表示这个数是丑数,但是这种方法显然不好,计算量大。另一种方法,类似于筛选素数的方法,我们将已经得到丑数,乘上2,3,5,那么新生成的数也一定是丑数,关键问原创 2012-09-09 15:31:23 · 1177 阅读 · 0 评论 -
判断一个后序遍历是否正确
题目:一棵二叉查找树,得到一个后序遍历,判断这个后序遍历是否正确。分析:方法1,根据中序和后序根据中序和后序,可以唯一得到一棵二叉树。一棵二叉查找树的中序显然就是所有数字的正常排序,所以,我们首先将所有的后序得到的数字排序,时间复杂度是O(nlogn),然后根据后序和中序遍历,判断二叉树是否可以建立。总的时间复杂度就是O(nlogn)。方法2,直接利用查找二叉树的性质显原创 2012-09-09 15:00:47 · 1714 阅读 · 0 评论 -
删除K个数字,使剩下的数字串最大
题目:一个n位的数,去掉其中的k位,问怎样去掉使得留下来的那个(n-k)位的数最大?分析:可以直接用贪心来求解,每次寻找从头开始的连续递减序列,删除递减序列的最后一个元素,重复K次,最后剩下的数字串组成的数字最大。比如:“13787323”第一次,递减序列只有1,删除1,得到3787323第二次,递减序列只有3,删除3,得到787323第三次,递减序列只有7,删原创 2012-09-29 11:29:03 · 6402 阅读 · 1 评论 -
字符串的组合
问题:输入一个字符串,输出该字符串中字符的所有组合。举个例子,如果输入abc,它的组合有a、b、c、ab、ac、bc、abc。分析:以前做过类似的题目,求解字符串所有的排列,采用的递归思路。二进制方法这个题我想到的第一种方式是考虑到2^n的特殊性,如果字符串长度为5,我们可以有2^5中组合方式,则用二进制表示,第i位为1,表示输出string[i];如果为0,则不输出。原创 2012-08-25 10:52:34 · 873 阅读 · 0 评论 -
数对之差的最大值
问题:在数组中,数字减去它右边的数字得到一个数对之差。求所有数对之差的最大值。 例如在数组{2, 4, 1, 16, 7, 5, 11, 9}中,数对之差的最大值是11,是16减去5的结果。分析:1,分治法将一个数组分为两部分,分别求解左边最大之差和右边最大之差,合并的时候再计算左边最大值和右边最小值之差算法如下:#include #include #include原创 2012-08-25 10:05:16 · 861 阅读 · 0 评论 -
二维数组中的查找
问题:给定一个二维数组,这个二维数组的每行、每列数字都是递增的,查找某个整数是否在二维数组内。分析:这题和堆排序有类似,查找过程中从右上方的数字开始,如果该数字比查找的数字小,那么该数字所在行可以删除,不用继续考虑;如果该数字比查找的数字大,那么该数字所在列可以删除。这样,每次执行,都会删除一行或者一列,极端情况下,执行2n次。算法代码:#include #include原创 2012-09-02 20:46:38 · 1894 阅读 · 1 评论 -
插座问题
题目:设有28盏灯,拟公用一个电源,则至少需有4插头的接线板数多少个?分析:看到这个题,可以将插座相连的情况看做一棵树,那么我们可以采用树的特性来求解。假设需要的接线板数目为X,我们可以得到如下不等式4 * X >= 28 + ( X - 1)其中不等式左边表示X个插座共有4*X个接口;等式右边表示插座提供的接口一部分给用户用:28个,另外一部分用来接插板自身的插头,这里有原创 2012-08-31 16:21:22 · 2288 阅读 · 0 评论 -
把数组排成最小的数
问题:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个。例如输入数组{32, 321},则输出这两个能排成的最小数字32132。分析:采用比较的方式,通过分析发现,如果m和n两个数字连成新的字符串,如果该mn>nm,那么n应该放在m之前,这样产生的新字符串组成的数字最小,这样我们可以采用排序的方式,只是排序中,采用的比较函数compare不是原来的基原创 2012-09-01 16:19:52 · 626 阅读 · 0 评论 -
复杂链表的复制
问题:有一个复杂链表,其结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中的任一结点或者NULL。结构体定义如下:struct complex_node{int value;struct complex_node *next;struct complex_node *sibling;};分析:简单的方法就是根原创 2012-09-01 17:05:08 · 674 阅读 · 0 评论 -
向量旋转问题
问题:《编程珠玑》里面典型的向量旋转问题。分析:直接转载的,认为写的比较好--------------------------------------------------------问题描述如下:Rotate vector x[n] left by d positions. 把x[n]向左旋转d个位置。例如:当n=8, d=3, 把abcdefgh向左旋转3转载 2012-09-02 10:08:01 · 1094 阅读 · 0 评论 -
计算可能组合数目的数学期望
题目:在一个盒子里面有N根绳子,这个N根绳子的中间部分放在盒子里面,不可见,但是这个N根绳子的两端露在盒子外面,所以我们能看到2N个绳头。 随机选取2个绳头并打结,直到所有的绳头都打上结。最后这些打结的绳子会形成许多环。请问环数目的期望值是多少?分析:以下内容直接从另外的博客转载的:------------------------------------------------转载 2012-09-02 10:33:37 · 2222 阅读 · 0 评论 -
二维矩阵求解最大移动距离
问题:N*N的表格中存放自然数,从任意位置开始,表格中的数字可以向四邻域移动(前提是移动方向上的数字必须小于当前数字),移动一次距离加一。求最大移动距离?分析:问题可以看成是一个动态规划问题,H[i][j] = max{H[i-1][j], H[i+1][j], H[i][j-1], H[i][j+1]} + 1,其中满足a[i][j] > a[i-1][j]等条件。经过和GJ原创 2012-08-31 23:50:00 · 1012 阅读 · 0 评论 -
求解字符串中最长对称字符串长度
问题:输入一个字符串,输出该字符串中对称的子字符串的最大长度。比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。分析:暴力法,穷举所有的子字符串,然后判断字符串是否是对称字符串,如果是,则计算出长度和当前最长的字符串比较,如果长度更长,更新结果。这种解法的时间复杂度为O(n^2)*O(n),前面的O(n^2)表示字符串的总数数量级,后面的O原创 2012-09-01 15:26:59 · 2793 阅读 · 0 评论 -
高效合并两个有序数组
问题:两个有序数组,合并成一个有序数组,假设第一个数组空间足够容纳两个数组。分析:考虑到a数组很大,可以直接在a数组上进行合并,但是要讲究效率。如果单纯从前往后合并,那么效率会非常低,因为a数组后面的数字需要不停的移动。换一种思路,我们采用从后往前合并,首先计算出总长度,设置一个指针从a数组最后往前移动。算法代码:#include #include #include us原创 2012-09-03 10:00:08 · 16226 阅读 · 7 评论 -
蚂蚁从一个角爬到对角的平均时间
题目:一个unit cubic,一只蚂蚁在一个角,准备在这个cubic的edge上开始爬动。蚂蚁爬过一条边的时间为1,它在任意一个角的时候,往其他三个方向去的概率都是1/3.问蚂蚁从一个角爬到对角的平均时间是多少?分析:直接转载的:---------------------------------------一个unit cubic,一只蚂蚁在一个角,准备在转载 2012-09-02 11:25:01 · 1300 阅读 · 0 评论 -
一致性hash算法 - consistent hashing
目录(?)[-]一致性 hash 算法( consistent hashing )基本场景hash 算法和单调性consistent hashing 算法的原理环形hash 空间把对象映射到hash 空间把cache 映射到hash 空间把对象映射到cache考察cache 的变动虚拟节点小结一致性 hash 算法( consistent hashing转载 2012-09-13 09:30:29 · 659 阅读 · 0 评论 -
两个数组a[N],b[N],其中A[N]的各个元素值已知,现给b[i]赋值
题目:两个数组a[N],b[N],其中A[N]的各个元素值已知,现给b[i]赋值,b[i] = a[0]*a[1]*a[2]...*a[N-1]/a[i];要求:1.不准用除法运算2.除了循环计数值,a[N],b[N]外,不准再用其他任何变量(包括局部变量,全局变量等)3.满足时间复杂度O(n),空间复杂度O(1)分析:好久没做题了,这次做一个比较简单的题,由于题目原创 2012-10-04 14:34:07 · 3869 阅读 · 3 评论 -
八皇后问题-递归和迭代两种解法
问题:经典的八皇后问题分析:递归解法直观易懂,但是迭代法需要想点思路代码如下:/* * eightQueen.cpp * * Created on: 2012-10-14 * Author: happier */#include using namespace std;#define N 8int sum = 0;int *x = new i原创 2012-10-14 14:24:33 · 7615 阅读 · 0 评论 -
跳表分析以及实现
题目:实现链表的快速插入、查询、删除等操作分析:我们知道,如果只是通过简单的单链表,我们对单链表的插入、删除、查询操作都是O(n)的,这里需要用到一种特殊的数据结构——跳表,能够实现高速插入、删除、查找,平均时间复杂度能够达到O(logn)(具体分析,有很多人写了专门的文章,由于跳表是基于概率的,所以时间复杂度不好分析)。跳表的核心思想,比如查找,让查找尽可能的快,所以我们第一次尝原创 2012-10-15 11:08:29 · 6459 阅读 · 0 评论 -
关于两个鸡蛋判断楼层问题
问题:经典的问题,给你两个鸡蛋,从100层楼上往下扔,从某个楼层开始,鸡蛋开始碎,请问最少扔多少次可以判断出楼层。分析:问题是经典的面试题,100层数据应该是14次,今天群里面同学给了一个解析解,(n+1)*n / 2这个通项解,直观上理解就是每次扔鸡蛋的楼层减1,第一次站在14楼扔,如果不碎,另一个鸡蛋从1楼开始往上走;如果14楼没碎,我们从(14+13)楼往下扔,如果没有碎,我们从原创 2012-10-18 19:42:02 · 5394 阅读 · 0 评论 -
环形打印矩阵
问题:环形打印矩阵,比如:1 2 3 412 13 14 511 16 15 610 9 8 7从外到内循环打印。分析:问题可以分解为4个问题,首先矩形向右走,到头后,再向下走,再向左走,最后向上走,如此循环,关键在于判断边界条件。代码:#include #define MAX 20int n,square[MAX][MAX]原创 2012-10-18 23:21:22 · 5088 阅读 · 0 评论 -
求正整数n所有可能的和式的组合
题目:给定一个数字n,求解出所有和为n的整数组合,要求组合按照递增方式展示,而且唯一。分析:最初看到这个题,没有什么特别好的思路,后来看了下别人的帖子,其实问题也没那么难,采用递归的方式进行求解,比如我们需要计算和为4的所有组合,我们首先将小于等于4的所有数字列出来1,2,3,4首先选取第一个数字,我们选取1,这时候,余下的和为(4-1),我们继续从1,2,3,4中选择,如此递原创 2012-10-19 15:12:11 · 6612 阅读 · 0 评论 -
主定理
当遇到形如T(n) = aT(n/b) + f(n)的递归表达式的时候,如果要用渐进符号表示T(n),每次都花时间来画递归树(Recursion Tree)显然不够经济。 在这个问题上,主定理给了我们一个捷径: 算法递推关系式运算时间备注折半搜索情形二(k = 0)转载 2012-11-04 10:17:57 · 2591 阅读 · 0 评论 -
12306网站设计
一位网友写的:http://www.360doc.com/content/12/0116/12/8674_179689611.shtml感觉写的不错,很全面。转载 2012-11-04 23:23:13 · 2785 阅读 · 0 评论 -
石子合并问题
i问题:经典的石子合并问题,不过现在简化为线性问题,而不是环形问题。放着n堆石子(n比如3 4 6 5 4 2最后得到的结果为:61分析:经典的DP算法,代码如下:其中通项式为:a[i][j] = min{k | a[i][k] + a[k+1][j] + sum[i...j], k = i...j-1}其中a[i][j]表示从第i堆到第j堆合并能够原创 2012-11-04 22:50:57 · 4750 阅读 · 0 评论 -
协同过滤概述
还没看完博客,但是感觉非常不错,果断转载地址了:http://www.vanjor.org/blog/2011/05/rs-collaborative-filtering/协同过滤转载 2012-10-26 22:49:55 · 2499 阅读 · 0 评论 -
递归转换成非递归思路
问题:非常经典的问题,将一个二叉树遍历,前序,中序,后序遍历由递归转换成非递归。分析:递归转换成非递归,一般解法是自己使用栈去模拟递归过程,首先我们来看下后序遍历递归解法:void postOrderTraverse(pNode root){if(root == NULL)return ;postOrderTraverse(p->left);postOrderT原创 2012-10-14 12:54:03 · 7297 阅读 · 0 评论 -
KMP算法
题目:经典的KMP算法分析:和KMP算法对应的是BF算法,其中BF算法时间复杂度,最坏情况下可以达到O(n*m),而KMP算法的时间复杂度是O(n + m),所以,KMP算法效率高很多。但是KMP算法不太好理解,其中牵涉到next数组,目标就是让模式串尽可能的往右滑动,减少比较次数,比如a b a b c-1 0 0 1 2比如我们比较ababc时,如果c原创 2012-10-09 11:11:52 · 6296 阅读 · 2 评论 -
原地矩阵旋转
题目:原地矩阵旋转,只使用O(1)空间进行旋转分析:假如是一个一维数组,我们很容易进行旋转,但是对于二维矩阵,没有好的思路,不过大体思路应该和一维类似,找到网上有人介绍,直接转载过来,还有点看不明白,但是代码实现了,作者是正确的。-------------------------------矩阵的存储结构是用一块线性内存来存储数据,然后记录宽度、高度,大致如下c原创 2012-09-17 14:52:17 · 1737 阅读 · 4 评论 -
字典树数据结构
题目:编写Trie树基本操作,包括插入,搜索,销毁分析:字典树,就是一棵26叉树(不考虑树的字符的大小写问题),在每个节点中加入计数器,表示从根节点到达当前节点的字符流表示一个字符串,代码如下:#include #include using namespace std;#define ELEMENT_MAX 26typedef struct trie_node{原创 2012-10-04 15:38:35 · 3751 阅读 · 0 评论 -
调整数组顺序实现:奇数在偶数前面 以及 “奇偶奇偶”相间
问题:问题一,需要重新排列数组,使得数组的奇数在前面,偶数在后面;问题二,使得“奇偶奇偶”相间,时间复杂度为O(n)。空间复杂度是O(1)。分析:第一个问题,马上想到的就是用两个指针的方法,一个放在头,一个放在尾,同时往中间走,不符合条件,再交换头和尾。第二个问题,没有什么好的思路,看到网友的思路,还比较认同的,但是时间复杂度有待商榷。代码如下:#includeusi原创 2012-10-04 17:31:00 · 1454 阅读 · 2 评论 -
全排列—存在重复元素
问题:全排列问题,但是存在重复元素,比如babc,求全排列,要求全排列不能包含重复串分析:由于存在重复元素,经典的全排列-递归方式不能达到题目要求,可以在原有全排列的基础上加入判断,还要对所有元素首先进行一次排序,具体代码如下:#include #include using namespace std;void SubPermutation(char a[], int s原创 2012-10-04 18:51:18 · 1674 阅读 · 0 评论 -
简单题-不用库函数,求解一个数字的平方根
题目:如标题所示,不用平方根库函数,求解一个数字的平方根。分析:这个问题有两个思路:思路1:采用二分的方式(无处不在的二分),上界初始化为数字本身,下界初始化为1,这样用二分,判断中间数字的平方和目标数字比较,再修改上界和下界,直到小于一定的阈值。思路2:采用牛顿法(数值分析中提到),采用微分的方式,从初始点开始,每次迭代,微分求解切线,然后求解切线和x轴的交点,再以这个交点作原创 2012-10-04 23:14:11 · 8495 阅读 · 0 评论