《编程之美》笔记
Erorr
Erorr
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
读书笔记之编程之美 - 4.10 数字哑谜和回文
好久没有写代码了,今天练习练习第二个问题,代码如下: 1: #include 2: 3: using namespace std; 4: 5: int main() 6: { 7: int m1, m2, m3, m4, m5; 8: int n1, n2, n3, n4, n5;原创 2010-09-23 22:42:00 · 1926 阅读 · 0 评论 -
读书笔记之编程之美 - 3.8 求二叉树中节点的最大距离
这个问题的难度是一颗星,主要其并不要求指出最远的那个两个节点。 由于是二叉树,采用递归的方式应该是比较合理的,非递归需要保存的数据比较多,而递归的用过就可以释放掉了。原创 2010-09-11 21:31:00 · 733 阅读 · 0 评论 -
读书笔记之编程之美 - 3.7 队列中取最大值操作问题
又要完成队列任务,又要保存最大值。 解法一用便利的方法肯定是最笨的方法,至于小飞提出的想法,如果有Dequeu操作,需要判断是否把最大值出队了,如果是,就需要重新遍历找到下一个最大值,其实也是可行的。 解法二把事情搞复杂了,搞出一个堆,然后还要保存插入的顺序。 解法三用了个技巧,需要Dequeue的时候,从一个栈往另一栈倒入数据,直到这个栈完全清空,然后再倒。 我想,其实简单维护两套队列就行了,一个是插入顺序的,一个是排序顺序的,然后两个队列之间建立起关联。不过算法三的技巧值得学习。原创 2010-09-10 21:29:00 · 1714 阅读 · 2 评论 -
读书笔记之编程之美 - 3.2 电话号码对应英语单词
这个问题可以参考《编程珠玑》第2.8节”实现变位词程序”,但不需要排序。首先把字典里的词都转化为数字,然后查找这些数字就可以了。 问题一的解法和题意有点差距,应该把题意变成遍历所有可能的字符串。因为解法中并没有提供查找过程。而且根据问题2解法二就不需要这种遍历了。不过这两个解法中用到了一些技巧,如用number[]和answer[]保存数组的下标。 问题二的解法主要考虑解法二的技巧,另外这个应该是T9输入法的应用。原创 2010-08-27 21:04:00 · 1038 阅读 · 0 评论 -
读书笔记之编程之美 - 3.5 最短摘要的生成
书上的分析和解法,其实是如何在一个序列中寻找另一组关键词数组。解法二好像是记录了下次扫描的开始地址。但有个问题是,“微软亚洲研究院”如果分词会成为“微软/亚洲/研究院”,这样W数组中的词是分过的,而Q数组里面的是没有分词过的,如何匹配呢。其中提出的最短长度也没有搞清楚是什么。感觉有点迷糊,先把问题留下,以后再考虑吧。原创 2010-08-30 22:19:00 · 1973 阅读 · 0 评论 -
读书笔记之编程之美 - 3.4 从无头链表中删除节点
看完这个题真的是没有头绪,不过看完答案还是挺巧妙的,用了一版“狸猫换太子”。 扩展问题: 因为有了前面的基础,这个问题可以用反转next指针来完成,虽然指针需要仔细一些,但注意一点应该没有问题,不写具体代码了。原创 2010-08-28 23:16:00 · 663 阅读 · 0 评论 -
读书笔记之编程之美 – 3.1 字符串移位包含的问题
这个问题虽然只有一颗星,但让我想却只能想出解法一的笨解法。看完答案才恍然大悟,原来有这么一个简单解法,而且似曾相识。想起以前2.14节的那个数组首尾相连的问题,是不是也能用这种方法求解啊。 PS: 不知不觉中已经看到了第3章,书看了大概2/3,写读书笔记似乎成了看书的动力。我是个完美主义者,既然已经看到了这里,坚持一下就把这本书看完了。有点不太好的地方就是要写60多篇blog,太占地方了。原创 2010-08-26 20:32:00 · 565 阅读 · 0 评论 -
读书笔记之编程之美 - 2.20 程序理解和时间分析
问题1: 代码的关键是那个break,如果找到3个不能整除的数,内层for循环就退出了,必须正好从30个数里面找到2个数不能整除,而且这两个数还要连续。所以问题一的答案是,某个数不能且仅不能被2~31之间连续的两个数整除。 问题2: 这个问题先看看是否任意连续两个数都可以作为结果用到的那两个数。 分析rg[]中15 = 3 x 5这个数,如果某数可以被3和5整除,那么也一定能被15整除,因此15不可能是连续2个数中间的一个,例如30可以被3和5整除,则一定可以被15整除,这样15就不会是结果可以用的原创 2010-08-25 14:09:00 · 2657 阅读 · 0 评论 -
读书笔记之编程之美 - 2.21 只考加法的面试题
在纸上多列几个数字就不难发现,所有奇数都能分解成两个这样的数字x/2,x/2+1;如果能被3整除,就能写成x/3-1,x/3,x/3+1这样的;如果除4余2的数字,能写成x/4-1,x/4,x/4+1,x/4+2;等等。 问题1:代码如下 1: #include 2: 3: using namespace std; 4: 5: int func(int x)原创 2010-08-26 00:09:00 · 1292 阅读 · 0 评论 -
读书笔记之编程之美 - 2.19 区间重合判断
这个问题第一感觉也想到了解法二,肯定是先合并区间,然后再判断源区间是否在这些区间的组合里面。 不过解法一应该可以应用到扩展问题里,二维空间的覆盖可以把其他窗口和源窗口的重合部分保存起来,看最后能否全覆盖源窗口。原创 2010-08-23 23:45:00 · 1869 阅读 · 0 评论 -
读书笔记之编程之美 - 2.16 求数组中最长递增子序列
寻找数组最长的递增子序列,需要每次都从头遍历这个数组。即需要遍历的次数为1+2+…+N=N(N+1)/2,所以时间复杂度为O(N^2)。 解法一用了一个数组LIS[]保存每个子数组的最大长度。 解法二又用了一个数组MaxV[]来保存数据,但复杂度还是O(N^2)。 解法三说是利用二分法可以把复杂度降低到对数级别,没仔细研究,感觉解法一比较清晰吧,呵呵。 这个问题的收获还是利用多余的空间保存一个中间结果,然后求解,和前一节的解法有些类似。原创 2010-08-20 22:44:00 · 716 阅读 · 0 评论 -
读书笔记之编程之美 - 2.18 数组分割
拿到这个题目,首先想到的也是先计算sum/2,然后从2n个数组找出n个值的和正好为sum/2即可,但是有可能构造不出正好和为sum/2的情况。解法一就不说了,不是正确的解法。 解法二看似是动态规划,但是只计算出了可能的sum值,好像还是找不到是哪几个值排列组合出来的。另外,也不知道那个O(2^N)是怎么算出来的。 解法三有个勘误,for(i = 1; (i = 1; i—); 扩展问题:如果数组中有负数,没看出有啥不一样的,还是一样的算法吧,因为给所有的数都加上最大的负数的绝对值,就变成正的了。原创 2010-08-23 23:34:00 · 1011 阅读 · 1 评论 -
读书笔记之编程之美 - 2.15 子数组之和的最大值(二维)
把前一个问题扩展了一下,寻找二维数组中,从(x1, y1)到(x2, y2)确定的矩形区域的数据之和最大值。 解法一给出了一个技巧,建立一个和原数组一样大的数组,用来保存(0, 0)到(x, y)的和,即P[x][y] = sum(x[0][0] –> x[x][y])。然后用Sum = PS[i_max][j_max] - PS[i_min - 1][j_max] – PS[i_max][j_min - 1] + PS[i_min - 1][i_min -1]。不知道书上为什么要让数组从1开始,然后把原创 2010-08-19 21:20:00 · 1110 阅读 · 0 评论 -
读书笔记之编程之美 - 2.13 子数组的最大乘积
看到这个问题,第一反应就是利用乘积的正负数关系,如果负数个数为偶数,则去掉一个最小的正数,如果负数的个数为奇数,则去掉一个最小的负数。不过看完答案后,知道自己没有考虑数组里面有0的情况。 换句话说,这个问题就是,从数组里面去掉一个数,让其他数的乘积最大,相信大部分人都不会想到解法一。原创 2010-08-17 23:00:00 · 720 阅读 · 0 评论 -
读书笔记之编程之美 - 3.9 重建二叉树
如果单纯的重建二叉树比较常见,但用编程实现还没有做过。不过用前序遍历和中序遍历重建二叉树规律还是比较简单的,应该不难。 扩展问题: 1. 如果节点上的字母是相同的,有可能结果不是唯一的,例如所有节点都用一个字母,那么任何形状的二叉树都是合理的。应该可以用动态规划的方法来求解。 2. 由于前序的第一个节点是根节点,从中序遍历里面找到这个根节点,然后从中序里看左右子树是否在前序里面是合理的。 3. 如果只知道前序和后序结果,可能会有歧义,所以不能唯一重构二叉树。原创 2010-09-12 17:08:00 · 749 阅读 · 0 评论 -
读书笔记之编程之美 - 3.3 计算字符串的相似度
这个问题暂时不研究了,没想明白,先留个位置。原创 2010-08-28 23:09:00 · 644 阅读 · 0 评论 -
读书笔记之编程之美 - 4.8 三角形测试用例
这一节好像是介绍怎么写测试用例的,记得当时校园招聘面试MS的时候,也让写测试用例,不过当时前面的题分数就不够,应该都不用看我写的用例了吧。 对于扩展问题2,主要应该是考虑另存文件名的问题吧,包含以下几个方面: 1. 判断当前的目录是否有权限可以写,是否有足够的空间 2. 文件名为空,文件名过长,以及包含有各种非法字符 3. 文件名已经存在,是否覆盖 4. 针对单字符和Unicode设计不同case 5. 带绝对路径和相对路径的的另存为原创 2010-09-22 23:21:00 · 1799 阅读 · 0 评论 -
读书笔记之编程之美 - 4.4 点是否在三角形内
一开始看到这个问题,想法是在直角坐标系内先连线,再想办法慢慢判断,但似乎没有好的实现方法,因为没有方法判断三角形的哪个顶点在另外一个顶点的什么位置,就和解法二一样,不太好找逆时针方向。万一找错就成了顺时针方向,不过只要方向一致,符号一致也可以,顺时针方向就是都在射线右方,叉积都为负。 解法一比较巧妙,其中用到了海伦公式,感觉比较亲切。记得海伦公式在我那时的课本里是没有的,我还是在初中和班上的一些牛人学的,几乎是作为镇山之宝使用的。原创 2010-09-22 14:23:00 · 1238 阅读 · 0 评论 -
读书笔记之编程之美 - 4.6 桶中取黑白球
其实从题意已经决定最后会走到XOR的道路上,取两个同色的是一种情况,两个异色的是另一种情况。 对于解法一,找到(-1, 0)和(1,-2)的规律后就差不多了 对于解法二,想到可以把所有的球进行异或操作确实不容易,不过这也和题意有关,得到结果后还要放进去,这样就满足了XOR的计算后的“左值”可以连续参与计算的条件。 扩展问题都已经有答案了,就不分析了。原创 2010-09-22 20:57:00 · 1089 阅读 · 0 评论 -
读书笔记之编程之美 - 4.3 买票找零 (太难了!)
这个问题一看就头大了,想出括号匹配问题并不难,但算概率就太麻烦了,连符号表示什么意思都忘了,以后再看吧。原创 2010-09-22 13:57:00 · 1535 阅读 · 0 评论 -
读书笔记之编程之美 - 4.9 数独知多少
自己看书没看懂,突然跑出来一个6次方,其实也是3!的意思。幸好书上给出了参考文献,基本上本节就是翻译那篇论文的。 论文地址为:http://www.afjarvis.staff.shef.ac.uk/sudoku/felgenhauer_jarvis_spec1.pdf 在往上级,都是讨论数独的资源:http://www.afjarvis.staff.shef.ac.uk/sudoku/ 人家准备这篇论文肯定不是一天两天的活,如果面试那么紧张的时间能找出答案,那确实很了不起了。原创 2010-09-23 21:31:00 · 2301 阅读 · 0 评论 -
读书笔记之编程之美 - 4.7 蚂蚁爬杆
这个问题的难点就是看透那个“穿透”的本质。 扩展问题: 1. 第i个蚂蚁离开的时间和别的蚂蚁路线是有关的,所以比较麻烦吧。 2. 如果在一个平面上运动,说不定会出现死锁的情况,6只蚂蚁组成三角形以上的情况就会出现。 3. 蚂蚁一共的碰撞也和蚂蚁的初始走向有关,应该可以分析的。 4. 放鸽子问题,应该是c x s / (a + b) 5. 不太清楚a是绝对速度还是相对速度,应该很简单。原创 2010-09-22 21:26:00 · 2170 阅读 · 1 评论 -
读书笔记之编程之美 - 4.5 磁带文件存放优化
从题意分析可以看出,如果访问概率相同,小文件应该排在前面,如果文件长度相同,概率大的应该在前面。即和文件长度成反比,和概率成正比。 不过书上给出的例子只有一种情况,比如概率/长度相同的情况是否满足解答呢。 例如A和B的访问概率P分别为0.6和0.4,长度L分别为6和4,这样应该无论怎么排列都是相同的,计算如下: 0.6 x 6 + 0.4 x ( 6 + 4) = 7.6 0.4 x 4 + 0.6 x (6 + 4) = 7.6 说明用P/L排序是正确的。原创 2010-09-22 19:57:00 · 969 阅读 · 0 评论 -
读书笔记之编程之美 - 4.2 瓷砖覆盖地板
用1x2的瓷砖覆盖NxM的地板,只要N和M不都是奇数就行了。 扩展问题最后成了一个类似Fibonacci数列的问题。 对于其他问题,暂时没有找到答案。 用pxq覆盖MxN的地板,首先要保证MxN的面积可以整除pxq的面积,然后如果M可以整除p和q中的一个,N可以整除另一个的话就绝对没问题,否则要看M或N之中的一个是p和q的公倍数,这样还有能覆盖的可能,等等。原创 2010-09-22 13:25:00 · 2303 阅读 · 0 评论 -
读书笔记之编程之美 - 4.1 金刚坐飞机问题
最后一章是数学问题,虽然自认为数学学得很好,但学过的大都还给老师了,真正遇到这类问题还是比较麻烦的。 对于第一个问题,其实无所谓金刚,大家都是金刚,就是一个简单的随机问题。答案是1/N。举例来说,只有两个人,第一个人坐自己座位的概率是1/2,第二个人的概率是1/2 x 1 + 1/2 x 0 = 1/2,还是1/2。 对于第二个问题,书上的解答好像也有点问题,认为金刚就是1号乘客,而题上并没有这么说,所以应该假设金刚的票是k。 如果n=k,金刚正好坐在自己位置,那么所有人的概率都是1。 如果n!=k原创 2010-09-21 00:13:00 · 1567 阅读 · 0 评论 -
读书笔记之编程之美 - 3.11 程序改错
忘了是在哪本书上看的,第一个没有问题的二分查找算法,是经过了很多年的完善才出现的,说明很多大师级的人都无法一次写出这样的程序。 关于溢出的问题之前已经有所了解,算是一个基本技巧吧。而边界问题要仔细设计用例才能保证没有问题。 本来想写扩展问题的,可是不知道链表的长度,另外可能需要再保存一个多余的链表,也很麻烦,这个问题先不做了,上网看了看资料,还有什么追赶算法,了解一下为止。原创 2010-09-19 19:40:00 · 1906 阅读 · 5 评论 -
读书笔记之编程之美 - 3.10 分层遍历二叉树
普通的二叉树遍历,就是前序、中序和后序。现在要分层遍历,需要一个变量保存一下节点的层数或距离。解法中是用函数参数保存的,并且用了递归来查找特定的层数。不过这样重复遍历很多次。 后面给出的解法用了一个数组保存每层节点下一层的节点,然后遍历下一层再保存下下一层的节点,直到最后。这也是这个问题的技巧所在吧。 对于扩展问题,把数字看成一个栈,保存了每层的指针后就可以输出了。原创 2010-09-17 23:19:00 · 893 阅读 · 2 评论 -
读书笔记之编程之美 - 3.6 编程判断两个链表是否相交
看到这个问题,首先想到的解法也是解法一,于是就落入了陷阱。其实根本原因是理解和沟通的问题,如果强调一下只需要判断是否相交,而不需要找到相交的第一个节点,那肯定会多动一下脑子。而我错就错在没有仔细分析需求,而习惯性地想到找到第一个节点。 解法二也比较直接,缺点是需要大量存储空间,不过在扩展问题2中,这个解法可以成功,而且比解法一更好。 解法三利用了技巧,类似引入辅助线。但判断环也比较麻烦,不太可取。 解法四充分利用了需求和规则,应该是最符合题意的解法了。 扩展问题: 1. 如果链表上有环,也分为一个原创 2010-09-01 22:15:00 · 814 阅读 · 0 评论 -
读书笔记之编程之美 - 2.11 寻找最近点对
看了几遍也没看明白。对于一维的情况比较容易理解,但二维是不同的,书里面的解法似乎还是按照一维的解法在想问题。用x=M把点分成两部分,还说AD、BD不可能成为最近点对,而事实上它们是可能的!所以剩下的解释没法再看下去了。 不过扩展问题还是有收获的,介绍了一个抽屉原理。原创 2010-08-16 23:00:00 · 1512 阅读 · 3 评论 -
读书笔记之编程之美 - 2.14 求数组的子数组之和的最大值
第一次遇到这个题是在Autodesk的笔试题,由于笔试时间比较短,当时只写了个大概思路。 当时我的想法是正负数问题,先从前扫描,把数组的值都加起来,如果某时的sum为负数,则可以丢弃之前的数据,从新开始计算。另外还要从后面进行计算,遇到sum为负数也要进行数据截断。现在看这个解法有个问题,就是数组全为负数的时候,找不到答案,还要补充一步,寻找最大的那个负数。 再看书上的解法,直接看代码清单2-27,nStart = max(A[i], nStart + A[i]),这句的意思就是判断数组后面的结果是否可原创 2010-08-18 22:08:00 · 825 阅读 · 4 评论 -
读书笔记之编程之美 - 1.14 连连看游戏设计
这几节开始了游戏程序设计,都是Windows编程。这部分没有学好,什么设备、资源、消息队列都不清楚。不过其实也没有什么技术含量,熟练工而已,涉及到算法更没啥意思了。书中给出的广度优先算法有点复杂了,其实只要考虑3种情况就可以了:直连、一个折点和两个折点的情况。直接搜索这几种情况就行,而不用像迷宫那用先搜索出路径再判断折点。原创 2010-08-05 19:34:00 · 1491 阅读 · 0 评论 -
读书笔记之编程之美 - 1.13 NIM(3) 两堆石头的游戏
<br />从取石头的问题,最后分析到了一组序列的生成问题。最后的那个证明没看,我想在真正面试的时候,我不可能找到这样的算法,不过分析过程是可以分析出来的。<br />从这个问题,又想起了那次解决汉诺塔的非递归问题,其实只要有规律的问题,都是可以找到简单解法的。<br />不过这类问题,算法太过抽象,写过一遍后自己都会忘记,更不用说维护的人了,万一有问题,除非更牛的人看到了,否则没人敢去改。原创 2010-08-03 23:00:00 · 1370 阅读 · 0 评论 -
读书笔记之编程之美 - 1.12 NIM(2) “捻”游戏分析
分析出偶数必胜的结论不难,但是怎么找出异或关系的,看来真得考验一下真功夫了,不看答案真想不出来。实现了一下书上的算法,代码如下:#include int a[] = {3, 4, 6};using namespace std;int nim(int *p, int N){ for (int i = 0; i 0; j--) { int result = 0; // Save current value int temp = p[i]; // Set原创 2010-08-03 21:15:00 · 1563 阅读 · 1 评论 -
读书笔记之编程之美 - 1.11 NIM(1)-排石头的游戏
<br />必胜的策略,似乎是博弈的概念。基本题目比较简单,已经分析出必胜的策略。考虑扩展问题,似乎当石头等于4个的时候,先手反而是必输的,同样7个的时候,也是必输的,由此推论1、4、7、10、是先手必输的。分析到7,10以后就没有分析,以后再求解吧。原创 2010-08-02 23:51:00 · 1784 阅读 · 2 评论 -
读书笔记之编程之美 - 1.10 双线程高效下载
<br />这个一个多线程问题,用到了semaphore和Mutex的概念。之前也遇到过多线程问题,但奇怪的是用的都是Mutex。今天看到这道题才对信号量有了更深入的了解。有空的时候研究一下Darwin Streaming Server里的代码,应该没问题的。<br />另一个收获是题目后面的故事。“提高程序效能的最高境界,就是把事情做了,同时又不让用户感觉到程序在费力地做事情”。也许我们没有办法一次把事情做好,但不断改进的办法总是有的,另外这种客户体验很重要。原创 2010-08-02 21:11:00 · 1437 阅读 · 3 评论 -
读书笔记之编程之美 - 1.9 高效率地安排见面会
<br />题目标志了一颗星,20分钟内解决,结果看里面给出图的最少着色问题就结束了,因为这个着色问题至今没有有效的算法。不知道微软面试有没有哥德巴赫猜想的证明问题,如果面试者说现在还没能证明,会不会直接被请出去了呢。<br />查了一下算法导论,没有找到着色问题,看来已经超出我现在所能及的范围,等日后再回来研究吧。原创 2010-08-01 23:26:00 · 1887 阅读 · 1 评论 -
读书笔记之编程之美 - 1.7 光影切割问题
<br />这个问题用解法一来看,是一道几何题,一个平面被直线分割的部分和直线的个数及交点个数有一定规律,找出这个规律就得到答案。<br />解法二就比较牛了,发现了直线交叉的的个数和直线在另外一条边上的逆序数相等。<br />当我们发现直接求直线交点比较难的时候,就可以去求那个逆序数。<br />反过来想,如果要求解一个序列的逆序数,我们也可以构造这样一堆直线,然后数一数交叉点呢。<br />至少答题的时候,用人眼数交叉点要比求逆序数容易一些;另外,我们也可能会发现求交叉点比较容易的算法也说不定。原创 2010-07-30 20:45:00 · 1876 阅读 · 0 评论 -
读书笔记之编程之美 - 1.8 小飞的电梯调度算法
<br />最近在给公司一技术大牛打杂,他对我的评价是有点小聪明,但缺点啥,形容不出来。我想是有点浮躁吧,喜欢轻易下结论。<br />回到这个题目,第一印象就是书上算法有点垃圾,让出题这个人从1加到100,他准用for循环实现。<br />我的第一感觉是,求电梯停的位置,只要求出所有人爬的总楼层数,然后按人头求个平均值就行了!<br />不过把我的算法和书上的算法一对比,发现有些结果对不上,手算发现自己的算法有问题,平均值是不行的,也许应该求中位数之类的。但转念一想,我的想法还是有价值的,因为求出平均值后,原创 2010-07-31 20:40:00 · 2309 阅读 · 3 评论 -
读书笔记之编程之美 - 1.6 饮料供应(错误连篇)
<br />这道题目是目前为止这本书里最烂的一个。第一版的勘误表里就错误一堆,改正了以后还是一堆垃圾。不过话说回来,也不能求全责备,毕竟不是只有优秀的人才能进微软,偶尔也会混进几个菜鸟。<br />本节中的符号错乱就不说了,算法一的代码也有点问题,逻辑上有疏漏。第二层for循环的opt[i][j] = -INF应该写成opt[i][j] = opt[i-1][j],意思是容量大了以后,至少不会小于上一个容积的满意度。<br />为了方便,我的代码把-INF改成-1,代码清单如下:<br />#include原创 2010-07-29 23:22:00 · 2106 阅读 · 5 评论 -
读书笔记之编程之美 - 1.5 快速找出故障机器
问题的本质在解法一里面已经分析得很清楚了,其实就是一堆数字,挑出一个或多个,通过剩下的一堆推算出那个挑出的是什么数字。分析到解法四,已经在时间和空间负责度上都达到了比较好的程度。一个小技巧就是xy=b和x^2+y^2=b这两个等式哪个不容易溢出。当然是后者平方和这个,因为xy最后会成为x^N,而x^2+y^2最后是N*x^2。当N比较大时,指数增长很快。扩展问题:如果有3个备份,同时有3个机器死机的情况,还是可以用解法四来解,就是构造3个方程组就行了。推广到N的情况,好像解方程组比较困难了,还是用解法二的思原创 2010-07-27 00:00:00 · 1663 阅读 · 0 评论
分享