算法的优雅(一)杂谈

最近一直在看各个公司的面试笔试题,而且仔细研读《编程之美》这本书,为了大四实习准备,之后发现那些题很值得玩味,所以想自己写出了,一是和大家分享自己的想法,二是给那些和我一样准备工作的同学,虽然面试的题都是基础,但需要很奇特的思维模式,所以,从现在开始训练为时不晚。

所有题都能google到,而且很多都附有题解,而我写这个的原因就是没题解的补充一下,有题解的我只写我自己的想法,或者把那些晦涩难懂的题解写的更白话些,同时很多题都值得玩味,比如微软的12个小球找不同等,那些都需要专门好好写一下。而且,我只会写算法方面的题,至于纯系统理论或者网络的,一我也不太明白,专业课正在上,二这个算法的优雅,你懂得。


一.1-20的两个数把和告诉A,积告诉B,A说不知道是多少,B也说不知道,这时A说我知道了,B接着说我也知道了,问这两个数是多少?

这类题很经典,在传闻中的google面试题中也出现过,分析方法就是从两人对话入手。

首先,A说不知道,所以两数之和可分解的情况不唯一,同理,B也说不知道,两数之积可分解情况也不唯一,但在这之后A说知道了,说明和能拆分成两种情况,而其中一种的积的拆分是确定的,这样A就排除了积拆分唯一的情况,所以知道了答案,而这种情况只有2和3或2和4.


二.请定义一个宏,比较两个数a、b的大小,不能使用大于、小于、if语句。

答案:#define   max(a,b)  ((((long)((a)-(b)))&0x80000000)?b:a)

这个考察的是位运算和对符号位的理解。

long是32为整型,最高位是符号位,0是整数,1是负数,所以,用a-b强制转换成long,之后用一个32位,最高位是1,其他都是0的&上,得到的低三十一位肯定是0,如果是正数,那么与1还是0,所以整体与完还是0,否则是1.


三..不使用其他变量,交换两个整型a,b的值。

答案:

x = x+y; y = x-y; x = x-y;
不难,只是想到没想到的问题。


四.一个文件中有40亿个整数,每个整数为四个字节,内存为1GB,写出一个算法:求出这个文件里的整数里不包含的一个整数。

TX的题,涉及很大的数,乍一看很头疼,不会从题目仔细分析就能找到入手的地方。

每个整数4个字节,所以共有2^32=4GB种可能。

用1bit表示一个整数,则只需要500MB就能把4GB种情况表示出来了。先初始化500MB内存为0,读一个数相应位置表位1,最后遍历一下就行了。


五.在一个文件中有 10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。只写出思路即可。

同为TX的题,够恶心吧....不过可以借鉴一下上面的思路,就是把大数映射到内存上,减小内存开销,这样存入。

不过,上面那种映射显然行不通了,因为上面的可以忽略重复数,而这个不可以。

所以,我们先把这10G个数分成256M段,映射到2G内存上,这样每段内存有64位去存储。

假设整数是32位的,共有2^32-1=4G种情况,而分成256M段,每段记录16种情况,所以,0-15记录在第1段,16-31记录在第2段.....

每段64位,记录的是属于该段数出现的次数。

这样,读入10G个数,统计次数,之后从前向后累加,当个数超过5G时,记录下当前段[x, x+15],中位数就在当前段,释放之后的段空间,再读一次10G数,统计[x, x+15]中每个数的个数,之后结合前面段个数和,累加到再次超过5G,那么中位数就是当前数了。


这两道题共同的思路就是映射,将大规模通过映射放入小规模内存中,通过一系列算法求解。



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值