摘要: 编程之美--3.5最短摘要生成 Alibaba笔试题:给定一段产品的英文描述,包含M个英文字母,每个英文单词以空格分隔,无其他标点符号;再给定N个英文单词关键字,请说明思路并编程实现方法String extractSummary(String description,String[] key words),目标是找出此产品描述中包含N个关键字(每个关键词至少出现一次)的长度最短的子串,作为产品简介输出。(不限编程语言)20分。 这道笔试题和编程之美最短摘要生成的方法类似,我用java实现了这个方法。 先来看看这些序列:w0,w1,w2,w3,q0,w4,w5,q1,w6,w7,w8,q... 阅读全文
posted @ 2013-06-25 17:02 夜雨阑珊 阅读(863) 评论(0) 推荐(0) 编辑
摘要: 思路:最大公约数问题也是一个非常典型的递归算法的应用。每次递归使得原来求两个大数之间的公约数转变成求两个稍微小点的数之间的公约数,要求转换的过程要保证不会改变公约数的值。这就要看其中转换的原理了。原理从《几何原本》中得出--辗转相除。假设f(x, y) 表示x,y的最大公约数是g,而k = x/y,b= x%y,则g必能整出b。因为x = ky + b,b = x - ky,b/g = (x-ky)/g一定为整数,所以必有g整除b。如下所示:f(42, 30) = f(30, 12) = f(12, 6)= f(6, 0) = 6代码如下:[html]view plaincopyintgcd( 阅读全文
posted @ 2013-06-25 17:01 夜雨阑珊 阅读(322) 评论(0) 推荐(0) 编辑
摘要: 题目:给定两个字符串S1,S2,要求判断是否通过S1循环移位可以得到S2,比如说:S1 = AABCD,S2 = CDAA,结果返回true。给定S1=ABCD和S2=ACBD,结果返回false。方法1:最简单的就是将S1循环一遍,每一次都是将S1循环右移一位,然后和S2进行比较。效率低到O(len(S1)*len(S2)).代码:#include "stdafx.h"#include#include#include#include#include#include#include#includeusing namespace std;//O(len(s1)*len(s2) 阅读全文
posted @ 2013-06-25 17:00 夜雨阑珊 阅读(676) 评论(0) 推荐(0) 编辑
摘要: 题目:给定一个长度为N的整数数组,只允许使用乘法,不能用除法,计算任意N-1个数的组合中乘积中最大的一组,并写出算法的时间复杂度。解法: 实际上第一反应就是先将N个数相乘得到结果,然后遍历每一个数,看去掉哪个数最适合,注意正负号。效率O(N). 但是文章在最后指出不允许用除法的用意是这样的,乘法很容易溢出。意思是干脆乘法也不要用。文中给出如下几种算法:源码出自:http://blog.csdn.net/qq120848369/archive/2010/05/12/5583796.aspx算法一: 枚举每一个不在N-1内的数,分别计算剩余N-1个数的乘积, 由于有N种情况,每种情况遍历计算乘积, 阅读全文
posted @ 2013-06-25 16:59 夜雨阑珊 阅读(1772) 评论(0) 推荐(0) 编辑
摘要: http://www.cnblogs.com/flyoung2008/archive/2011/08/16/2141579.html中序和后序也能重构------------前序和后序好像不能重构----没找到资料已只二叉树的前序和中序遍历,要求构建出完整的二叉树 如前序遍历为:a b d c e f 中序遍历为:d b a e c f 由于前序遍历先访问的是根节点所以整棵树的根节点是a 中序遍历中,先访问左子树,再访问右子树,所以d b 是左子树,e c f 是右子树 如此递归下去,可以找到整棵树的结构#include #define TREELEN ... 阅读全文
posted @ 2013-06-25 16:58 夜雨阑珊 阅读(483) 评论(0) 推荐(0) 编辑
摘要: 问题描述:写一个程序,对于一个64位正整数,输出它所有可能的连续自然数(两个以上)之和的算式。例如:3=1+2; 9=5+4; 9=2+3+4。刚开始看到这个题目,直接想到的方法就是蛮力解决:即对于每一个输入的整数,从1开始加,一直加到等于或者大于这个整数为止。如果等于这个整数,则找到了一种连续自然数相加的模式;如果大于这个整数,则无法找到,继续从2开始加,依次类推。例如对于5来说,首先从1开始加:1+2+3=6>5,这样从1开始就无法找到,从而停止继续相加;然后从2开始相加:2+3=5,成功找到。这是很自然的一种想法,可以达到题目要求。但是,很显然工作量比较大,程序时间复杂度高。于是百 阅读全文
posted @ 2013-06-25 16:57 夜雨阑珊 阅读(516) 评论(0) 推荐(0) 编辑
摘要: Tango是微软亚洲研究院的一个试验项目。研究院的员工和实习生们都很喜欢在Tango上面交流灌水。传说,Tango有一大“水王”,他不但喜欢发贴,还会回复其他ID发的每个帖子。坊间风闻该“水王”发帖数目超过了帖子总数的一半。如果你有一个当前论坛上所有帖子(包括回帖)的列表,其中帖子作者的ID也在表中,你能快速找出这个传说中的Tango水王吗?分析与解法首先想到的是一个最直接的方法,我们可以对所有ID进行排序。然后再扫描一遍排好序的ID列表,统计各个ID出现的次数。如果某个ID出现的次数超过总数的一半,那么就输出这个ID。这个算法的时间复杂度为O(N * log2N + N)。如果ID列表已经是 阅读全文
posted @ 2013-06-25 16:56 夜雨阑珊 阅读(559) 评论(0) 推荐(0) 编辑
摘要: 原创文章,转载请注明出处~~ http://www.cnblogs.com/justinzhang/问题描述:给定平面上N个点的坐标,找出距离最近的两个点。 这是编程之美2.11的一道题目,从昨天到现在就一直在设法解决它;如果用常规的解法,只需要将N个点两两计算距离,然后找出最小距离的两个点就可以了;但是这种解法的算法复杂度为O(N^2); 为了降低算法的复杂度,我们需要有更好的方法。这里我们找到的解法是分治法。设点集为S,|S|=N,S的横坐标集合为Sx,纵坐标集合为Sy;算法的步骤如下:1.找出Sx的中位数:median_Sx;用median_Sx对点集S进行划分,左边的为S1,右边的为S 阅读全文
posted @ 2013-06-25 16:55 夜雨阑珊 阅读(2037) 评论(0) 推荐(0) 编辑
摘要: 这是编程之美书第2.5节的一道题目。各种解法:解法一,用nlgn复杂度的排序算法对数组进行从大到小排序,取前K个。但这方法做了两件不必要做的事:它对想得到的K个数进行了排序,对不想得到的n-K个数也进行了排序。方法不可取。解法二,用选择排序或冒泡排序,复杂度O(NK)。但这方法也做了不必要做的一件事:对想得到的K个数进行了排序。方法不可取。解法三,用顺序统计位(类快排)算法来计算(可参考算法导论)。算法导论上说这种方法从平均性能上来讲是线性的,但编程之美上却说复杂度是O(N*lgK)。对于这点,我对编程之美持怀疑态度。我认为,对于一个无序的数组,用顺序统计位算法,可以在近似O(n)的时间复杂度 阅读全文
posted @ 2013-06-25 16:54 夜雨阑珊 阅读(647) 评论(0) 推荐(0) 编辑
摘要: 最简单的方法就是N中的每个数分别和max,min比较,看似2N次比较,其实大于max的就不必和min比较,小于min的也不必和max比较,因此比较的次数不足2N次,程序如下:[cpp]view plaincopyboolMaxMin(std::vectorarray,T*max,T*min){if(array.size()*max){10. *max=array[i];11. }elseif(array[i]boolMaxMin_1(std::vectorarray,T*max,T*min){if(array.size()=array[index+1]){12. if(array[index] 阅读全文
posted @ 2013-06-25 16:52 夜雨阑珊 阅读(1463) 评论(0) 推荐(0) 编辑
摘要: 求数组中最长递增子序列写一个时间复杂度尽可能低的程序,求一个一维数组(N个元素)中的最长递增子序列的长度。例如:在序列1,-1,2,-3,4,-5,6,-7中,其最长的递增子序列为1,2,4,6。分析与解法根据题目的要求,求一维数组中的最长递增子序列,也就是找一个标号的序列b[0],b[1],…,b[m](0 1,2>-1。因此,最长的递增序列为(1,2),(-1,2),长度为2。在这里,2前面是1还是-1对求出后面的递增序列没有直接影响。(但是在其它情况下可能有影响)依此类推之后,我们得出如下的结论。假设在目标数组array[]的前i个元素中,最长递增子序列的长度为LIS[i]。那么, 阅读全文
posted @ 2013-06-25 16:51 夜雨阑珊 阅读(802) 评论(0) 推荐(0) 编辑
摘要: 设计一个算法,把一个含有N个元素的数组循环右移K位,要求时间复杂度为O(N),且只允许使用两个附加变量。不合题意的解法如下:我们先试验简单的办法,可以每次将数组中的元素右移一位,循环K次。abcd1234→4abcd123→34abcd12→234abcd1→1234abcd。伪代码如下:代码清单2-33RightShift(int* arr, int N, int K){while(K--){int t = arr[N - 1];for(int i = N - 1; i > 0; i --)arr[i] = arr[i - 1];arr[0] = t;}}虽然这个算法可以实现数组的循环 阅读全文
posted @ 2013-06-25 16:50 夜雨阑珊 阅读(10482) 评论(1) 推荐(2) 编辑
摘要: 题目概述:有一个没有排序,元素个数为2N的正整数数组。要求把它分割为元素个数为N的两个数组,并使两个子数组的和最接近。假设数组A[1..2N]所有元素的和是SUM。模仿动态规划解0-1背包问题的策略,令S(k, i)表示前k个元素中任意i个元素的和的集合。显然:S(k, 1) = {A[i] | 1N?N:k;i>=1;i--){//这点有点难以理解啊//两层外循环是遍历集合S(k,i)for(j=0;j=A[k]&&flag[i-1][j-A[k]])flag[i][j]=true;}}}for(i=sum/2;i>=0;i--){if(flag[N][i]){c 阅读全文
posted @ 2013-06-25 16:49 夜雨阑珊 阅读(4034) 评论(0) 推荐(0) 编辑
摘要: 求子数组之和的最大值是一个很经典的问题。问题的描述如下:一个有N个整形数的一维数组(A[0], A[1], ... A[n-1]),这个数组有很多子数组,那么子数组之和的最大值是什么呢? 这个问题的解答其实在《编程珠玑》一书有的。一共是4中方法:第一种是穷举法,计算所有可能子数组的和,时间复杂度为O(n3)。第二种其实也是穷举法。代码如下:[cpp]view plaincopyfor(i=0;imaxsum)maxsum=sum;}10. } 很明显复杂度为O(n2)。第三种方法是分治法,将数组元素均分成两部分,那么最大子数组和只有三种情况。在左边部分,右边部分,以及跨越了边界部... 阅读全文
posted @ 2013-06-25 16:48 夜雨阑珊 阅读(1000) 评论(0) 推荐(0) 编辑
摘要: 题目:给定一些无序区间,判断某个给定的特定区间是否在这些无序的区间内。这个题目比较简单,首先将给定的区间排序,在对重合的区间进行排序,使得区间变成递增且不重叠的若干个区间,对于给定的区间在已经处理好的区间内进行二分查找,完成区间覆盖的判断。程序如下:[cpp]view plaincopy#include#include#includeclassInterval{public:Interval(intstart,intend):start_(start),end_(end){}Interval():start_(0),end_(0){}staticboolOrderByStart(constIn 阅读全文
posted @ 2013-06-25 16:47 夜雨阑珊 阅读(1117) 评论(0) 推荐(0) 编辑
摘要: 问题描述:一个比较经典的问题,判断两个链表是否相交,如果相交找出他们的交点。思路:1、碰到这个问题,第一印象是采用hash来判断,将两个链表的节点进行hash,然后判断出节点,这种想法当然是可以的。2、当然采用暴力的方法也是可以的,遍历两个链表,在遍历的过程中进行比较,看节点是否相同。3、第三种思路是比较奇特的,在编程之美上看到的。先遍历第一个链表到他的尾部,然后将尾部的next指针指向第二个链表(尾部指针的next本来指向的是null)。这样两个链表就合成了一个链表,判断原来的两个链表是否相交也就转变成了判断新的链表是否有环的问题了:即判断单链表是否有环?这样进行转换后就可以从链表头部进行判 阅读全文
posted @ 2013-06-25 16:46 夜雨阑珊 阅读(542) 评论(0) 推荐(0) 编辑
摘要: 题目:有一根27厘米长的细木杆,在第3厘米,7厘米,11厘米,17厘米,23厘米这五个位置上各有一只蚂蚁,木杆很细,不能同时通过两只蚂蚁,开始时,蚂蚁的头朝向左还是右是任意的,它们只会朝前走或掉头,但不会后退,当任意两只蚂蚁相遇后,蚂蚁会同时掉头朝反方向走,假设蚂蚁们每秒钟可以走1厘米的距离。编写程序(C/C++),求所有蚂蚁都离开木杆的最小时间和最大时间。(百度面试题)读完这道题以后,我的想法是:最短时间考虑如下:首先标出木杆的中点,即在(0+27)/2=13.5厘米处。然后所有的蚂蚁都沿着木杆向离自己较近的一端走,这样所有蚂蚁都离开木杆的时间是最短的,即,为距离木杆中点最近的蚂蚁走向离它最 阅读全文
posted @ 2013-06-25 16:44 夜雨阑珊 阅读(1231) 评论(0) 推荐(0) 编辑
摘要: 2012-04-18 16:412.12快速寻找满足条件的两个数---程序员编程艺术之五第一节、寻找满足条件的两个数第14题(数组):题目:输入一个数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。要求时间复杂度是O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。例如输入数组1、2、4、7、11、15和数字15。由于4+11=15,因此输出4和11。分析:咱们试着一步一步解决这个问题(注意阐述中数列有序无序的区别):直接穷举,从数组中任意选取两个数,判定它们的和是否为输入的那个数字。此举复杂度为O(N^2)。很显然,我们要寻找效率更高的解法。 题目相当于,对每个 阅读全文
posted @ 2013-06-25 16:43 夜雨阑珊 阅读(658) 评论(0) 推荐(0) 编辑
摘要: 本人阅读了《编程之美》,参阅了其中的——计算字符串的相似度——一节。感觉颇为实用。现将这一文章贴于此处,并将代码赋予其后。 许多程序会大量使用字符串。对于不同的字符串,我们希望能够有办法判断其相似程度。我们定义了一套操作方法来把两个不相同的字符串变得相同,具体的操作方法为: 1.修改一个字符(如把“a”替换为“b”)。 2.增加一个字符(如把“abdd”变为“aebdd”)。 3.删除一个字符(如把“travelling”变为“traveling”)。 比如,对于“abcdefg”和“abcdef”两个字符串来说,我们认为可以通过增加/减少一个“g“的方式来达到目的。上面... 阅读全文
posted @ 2013-06-25 16:42 夜雨阑珊 阅读(1072) 评论(0) 推荐(0) 编辑
摘要: 分层遍历二叉树《编程之美》3.10问题:给定一颗二叉树,要求按分层遍历该二叉树,即从上到下按层次访问该二叉树(每一层单独输出一行),每一层要求访问的顺序为从左到右,并将节点依次编号。解:算法1printNodeAtLevel(Node *root, int level)if(level == 0 && root) 输出root->data returnif(root==NULL) returnprintNodeAtLevel(root->left, level-1)printNodeAtLevel(root->right, level-1)如果写成:print 阅读全文
posted @ 2013-06-25 16:41 夜雨阑珊 阅读(1366) 评论(0) 推荐(0) 编辑