小灰一边回忆一边讲述起当时面试的情景......程序员
题目:一个无序数组里有99个不重复正整数,范围从1到100,惟独缺乏一个整数。如何找出这个缺失的整数?面试
解法一:算法
建立一个HashMap,以1到100为键,值都是0 。而后遍历整个数组,每读到一个整数,就找到HashMap当中对应的键,让其值加一。数组
因为数组中缺乏一个整数,最终必定有99个键对应的值等于1, 剩下一个键对应的值等于0。遍历修改后的HashMap,找到这个值为0的键。3d
假设数组长度是N,那么该解法的时间复杂度是O(1),空间复杂度是O(N)。cdn
解法二:blog
先把数组元素进行排序,而后遍历数组,检查任意两个相邻元素数值是不是连续的。若是不连续,则中间缺乏的整数就是所要寻找的;若是全都连续,则缺乏的整数不是1就是100。排序
假设数组长度是N,若是用时间复杂度为O(N*LogN)的排序算法进行排序,那么该解法的时间复杂度是O(N*LogN),空间复杂度是O(1)。it
解法三:io
很简单也很高效的方法,先算出1+2+3....+100的合,而后依次减去数组里的元素,最后获得的差,就是惟一缺失的整数。
假设数组长度是N,那么该解法的时间复杂度是O(N),空间复杂度是O(1)。
题目扩展:一个无序数组里有若干个正整数,范围从1到100,其中99个整数都出现了偶数次,只有一个整数出现了奇数次(好比1,1,2,2,3,3,4,5,5),如何找到这个出现奇数次的整数?
解法:
遍历整个数组,依次作异或运算。因为异或在位运算时相同为0,不一样为1,所以全部出现偶数次的整数都会相互抵消变成0,只有惟一出现奇数次的整数会被留下。
假设数组长度是N,那么该解法的时间复杂度是O(N),空间复杂度是O(1)。
题目第二次扩展:一个无序数组里有若干个正整数,范围从1到100,其中98个整数都出现了偶数次,只有两个整数出现了奇数次(好比1,1,2,2,3,4,5,5),如何找到这个出现奇数次的整数?
解法:
遍历整个数组,依次作异或运算。因为数组存在两个出现奇数次的整数,因此最终异或的结果,等同于这两个整数的异或结果。这个结果中,至少会有一个二进制位是1(若是都是0,说明两个数相等,和题目不符)。
举个例子,若是最终异或的结果是5,转换成二进制是00000101。此时咱们能够选择任意一个是1的二进制位来分析,好比末位。把两个奇数次出现的整数命名为A和B,若是末位是1,说明A和B转为二进制的末位不一样,一定其中一个整数的末位是1,另外一个整数的末位是0。
根据这个结论,咱们能够把原数组按照二进制的末位不一样,分红两部分,一部分的末位是1,一部分的末位是0。因为A和B的末位不一样,因此A在其中一部分,B在其中一部分,毫不会出现A和B在同一部分,另外一部分没有的状况。
这样一来就简单了,咱们的问题又回归到了上一题的状况,按照原先的异或解法,从每一部分中找出惟一的奇数次整数便可。
假设数组长度是N,那么该解法的时间复杂度是O(N)。把数组分红两部分,并不须要借助额外存储空间,彻底能够在按二进制位分组的同时来作异或运算,因此空间复杂度仍然是O(1)。
十分钟后......
以上就是小灰面试的状况......
—————END—————
喜欢本文的朋友们,欢迎长按下图关注订阅号程序员小灰,收看更多精彩内容