编程珠玑学习笔记1

编程珠玑学习笔记1

最近经历了腾讯和百度的实习生招聘,腾讯的十分顺利,拿到实习生offer,可能运气成分多一点,问我的问题我都有所了解。百度虽然是霸笔的,但是还是的到了面试的机会,但是很不幸,百度二面的时候问了我一道概率题和一道智力题,感觉无从下手,答的很不好,应该是看你这个人的数学修养和思维活跃的程度。

总之,感觉面试还是十分注重基础知识的。我记得以前twitter上的徐宥说过准备算法类面试的时候,必看的几本书包括算法导论,编程珠玑和 TAOCP。算法导论我是没有全部看完的,虽然那本书看的不少,但是许多课后题没有去深入的思考,话说百度一面的时候就是算法导论上的一道原题。TAOCP太过大部头了,虽然我每次从去图书馆看到有这本就拿回来,但是基本没有看过,印象只停留在Kunth给了一个阅读本书的流程图,以及为了写着本巨著Kunth自己发明了一门语言。所以我准备从最薄的这本编程珠玑看起。

可以说这本书取的名字真的是很赞,作者Jon Bentley都是从一些小问题出发,然后讲述的十分透彻,不愧是大师级的人物。顺便提一下,Jon Bentley是James Gosling和Charles Leiserson的老师,前者是Java的设计者,后者就是算法导论别名CLRS中的L。

第一章主要阐述了一个位图(bitmap)算法,可以说算法中用到位操作的很多,因为速度快,空间小,比如哈有bitmask dp。文中的问题可以抽象为对[1:10000000]区间内的随机排列进行排序,而且内存限制在1m左右。外部排序可能是第一个闪近脑子里的答案。作者在文中的解法就是利用bitmap算法,每一个bit代表一个数字,用10000000个比特位就可以将所有的数字表示出来。然后遍历,设置1为存在,0为不存在,然后顺序输出即可。和这个题类似的有一个,而且是更加贴近现实的:

“你手中有一百万张纸,每张纸上是一个大学生的资料,你需要将他们按照年纪排序,你怎么做?谁更聪明,一个计算机科学博士还是你的母亲?在 Google 从事多年面试工作的 Paul Tyma 将这个问题交给他的母亲解答。从未学过计算机科学的 Tyma 夫人做的比受过高等教育的人还要出色。许多应试者会建议快速排序算法,而 Tyma 夫人的答案比他们的方法要快上 20 倍。有时候创造力只是常识。

答案:将纸堆上的第一张拿下来,看看年龄,如果他是 21 岁,就放到 21 岁的纸堆里,如果下一个是 19 岁,就放到 19 岁的纸堆里。如此这般,任何记录你只需要看一次,当你完成后,将不同年龄的纸堆顺序排列即可。”

不过这类问题的特殊性就是数据范围比较集中,比如1到10000000,年龄一般都在1-200之间,后一个题带有明显的计数排序和hash的影子。

习题部分非常的推荐,我是这样做的,首先写出自己的想法,然后再和答案进行对比。

下面是我认为比较好的题目:

4.如何生成位于0到n-1之间的k个不同的随机顺序的随机整数?

我的答案:找一个gcd(n,m)==1的数m,设一个起点x,那么x=(x+m)%n可以将所有的小于n的数遍历,为了产生视觉更加随机的感觉,可以把方程写为x=(x+m*p)%n,p这里是个素数。利用这个公式可以产生等概率而且不重复的k个随机值。

书上答案:

for i = [0, n)
    x[i] = i
for i = [0,n)
    swap(i, randint(i, n-1))
    print x[i]

5.文中10000000个数字利用bitmap进行排序大约需要1.25m的内存,假设限定内存为1m,问题该怎么解决?

我的答案:这个文中已经写过,进行2次遍历,第一次只处理0-4999999,第二次处理5000000-9999999.

书上的答案类似。

6.如果每个数字最多可能出现10次,如何建议?

10次的话可以用4个比特来代表一个书出现的次数,不过这样大约需要5m的内存,如果限定1m的话,可以进行5次遍历即可解决。

书上答案类似。

8.现在7位号码前面的区号不只是800了,还有其他诸如877和888等,如何在1m的空间内进行排序?

我给的答案有明显的时空转换的概念,现在一共10位数字,我取前k个作为排序的前缀,先对所以数字的前k位进行统计,只统计有或者无,这样消耗了10^k bits,遍历这10^k个比特位,同时遍历所有数字,取和当前的前缀相同的数字,对这些数字进行bitmap,总的空间复杂度为O(10^k+10^(10-k)),时间复杂度为O(10^k*10^10),对于k>5的情况不做考虑,因为得不偿失,在k取1到5时,空间是递减的,时间则是递增的。

书上只提示了用关键字索引。

9.设计一种第一次访问数据才初始化的方法。

我的答案是利用比特位进行标记访问过没,这样只需要初始化这些比特位。

我想我对这个题的理解有些偏差,原书貌似是数据量很大,但是访问量很小,请设计一种方法在第一次访问的时候初始化。所以书中设计了一种from,to数组索引的方法。我们只需要初始化访问的数据个数,这个数比较小。

10.数据库利用电话号码作为key,如何组织数据库进行高效的插入和检索?

这个我没有想到很好的方法,感觉利用数据库进行插入和删除应该很高效了把。如果不用数据库的话可以利用书中的bitmap的原理建立一个hash_map,这样就可以常量时间访问。

书中给出了一个甚至完全不需要计算机的方法:将100个箱子编号为0到99,将电话号码的后两位做索引值,并将其订单放入对应编号的箱子中,典型的hash,作者的话是“用顺序搜索来解决冲突的开放散列”。

11.40公里的两个地方要交换图纸,快递费用很高,请你设计一种方法解决。

我的答案是通过网络传输。

书上答案是用信鸽,可能当时的互联网还没有普及到现在的程度。

12.太空中能书写的钢笔研发的故事,在三傻大闹宝莱坞上也提到了,用铅笔。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值