面试圣经

Posted Liberal-man

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试圣经相关的知识,希望对你有一定的参考价值。

小桔科技 四面

面试官是个部门经理,比较和蔼,说话爱笑,比别的公司的总监层面的人严肃的面孔好多了,也让面试者轻松很多。总结下他问的诸多问题以及我的解法,先上几个

问题 1

有数字1、2、3….直到n+2的递增数列,每个数都是唯一不重复的,以1的步长增长的。去掉其中两个数,然后打乱次序,找出被去掉的数到底是哪两个?(n假设是10w,空间复杂度要求O(1))

答:

方法1:
这是我的回答
设这些数保存在数组A中,用一个10w+2大小的数组B标志某一个数是否出现,默认全部置0.顺序扫描A数组,对A中的每一个数i,去设置B[i]=1,则相对的没出现的数则B[i]=0;扫描完A后,再扫描数组B,发现B[i]=0的则为缺失的数。
时间复杂度:O(N+N+2)=O(N)
空间复杂度:O(N+2)=O(N)

这个方法是最容易想到的,但是要O(N)的空间,也就是10w+2这么大个数组,达不到题目O(1)的要求。面试官肯定不会是考你这个方法,必须得有别的方法。

方法2:
还想到的另外一个方法,用冒泡排序,但是时间复杂度太高,当时不确定别的排序的空间复杂度,就没敢说

对原数组A进行一次排序,然后从头到尾挨个扫描,发现相邻两个数的差不是1的时候,就可以确定这两个数之间少了一个数了。

回去查了下,冒泡排序、直接插入排序、选择排序、堆排序的空间复杂度都是O(1)。但是时间复杂度上,只有堆排序是O(N*logN)的复杂度,别的都是O(N^2)的,太高,面试官也不满意。而快速排序需要空间复杂度是O(N*logN),也被排除了。

看来这种方式最好的时间复杂度,也只是用堆排序
时间复杂度:O(N*logN)+O(N)=O(N*logN)
空间复杂度:O(1)

别忘了还有个建立堆的过程,也很复杂。所以这个方法也被排除了。

方法3:
回到家苦思冥想,才想到,还有bitMap这个方法,面试的时候一着急竟然忘记了,看来应急能力不行啊,有待提高

bitMap这种方式讲起来要有一大篇幅,大家可以自己去网上搜下这种结构。我这里就是简单的说下,一个字节有8个bit位,假如存在1,我们就让第一个bit位置1,不存在就置0;同理存在2,就把第二个bit位置0,3就第三个比特位。当扫描一次数组A之后,则会把n个位置的bit位都置为1,那么不存在的两个数,所对应的坐标比特位就是0,然后扫描所有的比特位,发现不是0的位置,就是我们要找的数。当然,10w个数,需要10w/8=1.25w个字节的内存空间,实际上空间依然是O(N/8)=O(N),只是常系数小一些.而且操作bit位可不像操作数组一样直接定位,而是通过位移的方式来操作的,这样时间开销更大。

时间复杂度:O(N)
空间复杂度:O(N)

这个方式也不行。

方法4:
这个方法是后来在网上找的。我面试的时候,只想到了可以算出来两个去掉的数的和,这便成了一个方程式,但是如何把这个和分解成两个数,我却百思不得其解。后来看到网上的办法,才想到,我只想了一半,另一半可以用平方和来再确定一个方程式,两个二元方程式是可以算出解的。看起来可以满足要求

设去掉的两个数为X和Y,则我们累加1到10W+2,这个可以用数学公式推导得到一个和Sum1;然后扫描数组,从第一位一直累加到最后一位,总共10w个数累加,得到Sum2,那么X+Y的值S1=Sum1-Sum2:
X+Y = S1
同理,我们可以得到1到10W+2的平方和 减去 数组A中每个数的平方和,从而得到X^2 + Y^2的值:
X^2 + Y^2 = S2
根据两个方程可以解出X和Y。
这里需要注意的是,计算平方和的时候有可能会越界,可以使用unsigned long long,或者一边加(1到[10W+2]的平方和)一边减(数组A中每个数)。

时间复杂度:O(N)
空间复杂度:O(1)


创建于 2017-05-19 北京,修改于 2017-05-20 北京

以上是关于面试圣经的主要内容,如果未能解决你的问题,请参考以下文章

程序员面试圣经|如何拿下编程面试?

Java 面试的“完美圣经”,有了这些还愁面试吗?

新鲜出炉!《2021年最新Android中高进阶面试圣经》,直线提升面试通过率

“完美圣经”1000+道32W字Java面试手册,看完直接上岸美团

年后跳槽涨薪必备《最新 Android中高进阶面试圣经》

Go学习圣经:队列削峰+批量写入 超高并发原理和实操